分布式系统基础:CAP定理与一致性
分布式系统基础:CAP定理与一致性
概述
分布式系统是现代应用架构的基础。本教程介绍分布式系统的基础概念,包括CAP定理、一致性模型和分布式事务。
1. CAP定理
// CAP定理:分布式系统最多只能同时满足以下三个特性中的两个
// C(Consistency):一致性 - 所有节点在同一时间看到相同的数据
// A(Availability):可用性 - 每个请求都能得到响应
// P(Partition tolerance):分区容错性 - 系统在网络分区时仍能继续工作
// CA系统:传统数据库(单机)
// CP系统:ZooKeeper、etcd、HBase
// AP系统:Cassandra、Eureka、DynamoDB
public class CAPExample {
// 在分布式系统中,P是必须的,所以只能在C和A之间选择
// CP系统:保证一致性,可能牺牲可用性
// AP系统:保证可用性,可能牺牲一致性
}
2. 一致性模型
// 强一致性:写入后立即可见
// 弱一致性:写入后可能不可见
// 最终一致性:写入后最终会可见
// 常用一致性协议:
// 1. Paxos
// 2. Raft
// 3. ZAB(ZooKeeper Atomic Broadcast)
public class ConsistencyModel {
// 强一致性示例:分布式锁
// 弱一致性示例:DNS解析
// 最终一致性示例:电商库存
}
3. 分布式事务
import org.springframework.transaction.annotation.Transactional;
// 两阶段提交(2PC)
// 1. 准备阶段:协调者询问参与者是否可以提交
// 2. 提交阶段:协调者根据参与者的响应决定提交或回滚
// TCC(Try-Confirm-Cancel)
// 1. Try:预留资源
// 2. Confirm:确认提交
// 3. Cancel:取消预留
// Saga模式
// 1. 每个服务执行本地事务
// 2. 如果失败,执行补偿事务
public class DistributedTransaction {
@Transactional
public void transfer(String from, String to, double amount) {
// 本地事务
accountService.deduct(from, amount);
accountService.add(to, amount);
}
}
4. 实际应用示例
分布式锁
import org.springframework.data.redis.core.RedisTemplate;
import java.util.concurrent.TimeUnit;
public class RedisDistributedLock {
private final RedisTemplate<String, String> redisTemplate;
public boolean tryLock(String lockKey, String requestId, long timeout) {
return Boolean.TRUE.equals(
redisTemplate.opsForValue().setIfAbsent(lockKey, requestId, timeout, TimeUnit.MILLISECONDS)
);
}
public boolean unlock(String lockKey, String requestId) {
String script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";
return redisTemplate.execute(
new DefaultRedisScript<>(script, Long.class),
Collections.singletonList(lockKey),
requestId
) == 1L;
}
}
分布式ID生成
// 雪花算法
public class SnowflakeIdGenerator {
private final long epoch = 1609459200000L; // 起始时间戳
private final long workerIdBits = 5L;
private final long datacenterIdBits = 5L;
private final long sequenceBits = 12L;
private long workerId;
private long datacenterId;
private long sequence = 0L;
public SnowflakeIdGenerator(long workerId, long datacenterId) {
this.workerId = workerId;
this.datacenterId = datacenterId;
}
public synchronized long nextId() {
long timestamp = System.currentTimeMillis();
if (timestamp < epoch) {
throw new RuntimeException("时钟回拨");
}
if (timestamp == lastTimestamp) {
sequence = (sequence + 1) & ((1L << sequenceBits) - 1);
if (sequence == 0) {
timestamp = tilNextMillis(lastTimestamp);
}
} else {
sequence = 0L;
}
lastTimestamp = timestamp;
return ((timestamp - epoch) << workerIdBits + datacenterIdBits + sequenceBits) |
(workerId << datacenterIdBits + sequenceBits) |
(datacenterId << sequenceBits) |
sequence;
}
private long lastTimestamp = -1L;
private long tilNextMillis(long lastTimestamp) {
long timestamp = System.currentTimeMillis();
while (timestamp <= lastTimestamp) {
timestamp = System.currentTimeMillis();
}
return timestamp;
}
}
5. 最佳实践
- 理解CAP定理:根据业务需求选择CP或AP
- 选择合适的一致性模型:根据场景选择强一致性或最终一致性
- 使用分布式事务框架:Seata、Atomikos等
- 设计幂等操作:确保分布式系统中的操作幂等
- 监控分布式系统:使用分布式追踪工具
总结
分布式系统是现代应用架构的基础。理解CAP定理、一致性模型和分布式事务,可以设计和实现可靠的分布式系统。