分布式系统相关知识总结
分布式系统 相关知识总结
1. 分布式理论基础
1.1 CAP 理论详解
CAP 定理:在分布式系统中,Consistency(一致性)、Availability(可用性)、Partition tolerance(分区容错性)三者不可兼得。
核心概念:
- 一致性(C):所有节点在同一时刻访问同一份最新的数据副本
- 可用性(A):部分节点故障后,集群整体仍能响应客户端请求
- 分区容错性(P):系统在时限内无法达成数据一致性时发生分区,必须在 C 和 A 间做出选择
实际应用:
- CP 系统:Etcd、ZooKeeper(强调一致性)
- AP 系统:Cassandra、DynamoDB(强调可用性)
- CA 系统:传统单机数据库(无分区容错)
2. 分布式锁
2.1 Redis 分布式锁实现
核心命令:
SET lock_key unique_value NX PX 10000
lock_key
:锁的键名unique_value
:客户端唯一标识NX
:key不存在时才设置PX 10000
:设置10秒过期时间
加锁条件:
- 原子操作完成读取、检查、设置锁变量
- 设置过期时间防止死锁
- 锁变量值能区分不同客户端
解锁 Lua 脚本:
if redis.call("get",KEYS[1]) == ARGV[1] thenreturn redis.call("del",KEYS[1])
elsereturn 0
end
2.2 Etcd 分布式锁实现
Etcd 特性:
- 强一致性:基于 Raft 协议保证数据一致性
- 租约机制:支持 TTL 自动过期
- 事务支持:原子性比较和设置操作
- Watch 机制:监听键变化事件
实现流程:
- 创建租约并设置 TTL
- 尝试在指定前缀下创建键(带租约)
- 检查当前创建的键是否为最小序号:
- 是:获取锁成功
- 否:监听前一个键的删除事件
- 业务处理完成后删除键释放锁
- 后一个客户端收到通知,重复判断流程
核心操作:
# 创建租约
etcdctl lease grant 10# 使用租约创建键
etcdctl put /lock/resource client1 --lease=1234abcd# 事务操作
etcdctl txn --interactive
对比总结:
- Redis:性能高,AP 特性,可能数据不一致
- Etcd:强一致性,CP 特性,性能较高,原生支持分布式锁
3. 分布式事务
3.1 分布式事务解决方案对比
方案 | 一致性 | 性能 | 复杂度 | 适用场景 |
---|---|---|---|---|
2PC | 强一致性 | 低 | 中 | 传统数据库、XA协议 |
3PC | 强一致性 | 中低 | 高 | 需减少阻塞的强一致场景 |
TCC | 最终一致性 | 高 | 高 | 高并发业务(支付、库存) |
Saga | 最终一致性 | 中 | 高 | 长事务、跨服务流程 |
消息队列 | 最终一致性 | 高 | 中 | 事件驱动架构 |
本地消息表 | 最终一致性 | 中 | 低 | 异步通知(订单-积分) |
3.2 各方案详细原理
两阶段提交 (2PC):
- 准备阶段:协调者询问参与者能否提交
- 提交阶段:根据准备结果决定提交或回滚
- 缺点:单点故障、性能低、资源锁定
三阶段提交 (3PC):
- 在 2PC 基础上增加询问阶段
- 降低阻塞时间,引入超时机制
- 仍无法完全避免数据不一致
TCC 模式:
- Try:预留业务资源
- Confirm:确认资源完成操作
- Cancel:失败时释放资源回滚
- 优点:高性能,减少资源占用
- 缺点:开发成本高,实现复杂
Saga 模式:
- 长事务拆分为多个短事务
- 每个短事务有对应补偿事务
- 失败时按相反顺序执行补偿
- 优点:性能较高,业务侵入小
- 缺点:只能保证最终一致性
可靠消息最终一致性:
- 业务操作封装成消息发送
- 下游系统消费消息执行操作
- 优点:实现简单,系统解耦
- 缺点:消息可能丢失或延迟
本地消息表:
- 业务与消息同库存储
- 后台任务轮询消息表通知下游
- 优点:简单可靠,无外部依赖
- 缺点:消息可能重复消费
3.3 Seata 框架
支持模式:
-
AT 模式(默认):
- 基于关系型数据库
- 自动生成回滚日志
- 记录数据前后快照
-
TCC 模式:
- 手动编写 Try、Confirm、Cancel
- 业务资源预留和确认
-
SAGA 模式:
- 长事务拆分为短事务
- 每个短事务有补偿事务
4. 分布式组件
4.1 RPC 远程过程调用
调用流程:
- 客户端调用:调用本地存根函数
- 请求发送:序列化调用信息并发送
- 服务器处理:反序列化并执行对应函数
- 结果返回:序列化执行结果返回
- 客户端接收:反序列化结果返回调用者
常见 RPC 框架:
- gRPC:Google 开发,Protocol Buffers 序列化
- Thrift:Facebook 开发,跨语言支持
- Dubbo:阿里巴巴开源,服务治理功能丰富
4.2 Etcd 分布式键值存储
核心特性:
- 强一致性:基于 Raft 算法保证数据一致性
- 高可用:支持多节点集群部署
- 租约机制:支持键的自动过期
- Watch 机制:实时监听键值变化
- 事务支持:原子性比较和设置操作
数据模型:
- 键空间:分层键空间,类似文件系统目录结构
- 版本控制:每个键维护版本号,支持历史查询
- 租约:绑定键的生存时间,自动清理过期键
应用场景:
- 服务发现:微服务注册和发现
- 配置管理:分布式系统配置存储
- 分布式锁:基于租约和事务实现
- 领导选举:集群主节点选举
- 元数据存储:分布式系统元数据管理
Raft 协议实现:
-
领导选举:
- 节点状态:Follower、Candidate、Leader
- 选举超时机制
- 多数派投票原则
-
日志复制:
- 领导者接收客户端请求
- 复制日志条目到跟随者
- 多数节点确认后提交日志
-
成员变更:
- 联合共识机制
- 在线配置变更
- 集群节点动态调整
5. 分布式场景解决方案
5.1 限流算法详解
固定窗口限流:
- 原理:固定时间窗口内计数,超阈值拒绝
- 优点:实现简单
- 缺点:窗口切换时可能产生两倍流量
- 问题:流量突刺现象
滑动窗口限流:
- 原理:将窗口切分为更小时间片,时间轴上滑动
- 优点:避免固定窗口的两倍流量问题
- 实现:每个小时间片独立计数,滑动时更新
漏桶限流:
- 原理:模拟水流过漏洞桶,恒定速率流出
- 优点:平滑流量,保护系统
- 缺点:
- 无法充分利用空闲资源
- 不能解决流量突发问题
令牌桶限流:
- 原理:以固定速率向桶中添加令牌,请求获取令牌执行
- 优点:
- 允许一定程度流量突发
- 最大程度利用系统资源
- 推荐:通常场景优先使用
5.2 限流算法对比
算法 | 平滑流量 | 允许突发 | 实现复杂度 | 适用场景 |
---|---|---|---|---|
固定窗口 | ❌ | ✅ | 低 | 简单限流需求 |
滑动窗口 | ✅ | ❌ | 中 | 一般业务场景 |
漏桶 | ✅ | ❌ | 中 | 需要流量整形 |
令牌桶 | ✅ | ✅ | 中 | 高并发场景 |
6. 分布式一致性算法
6.1 Raft 协议原理
核心设计:
- 领导选举:确保集群有唯一领导者
- 日志复制:领导者负责日志同步
- 安全性:保证状态机执行顺序一致
角色转换机制:
- 跟随者:接收领导者心跳,超时转为候选人
- 候选人:发起选举投票请求
- 领导者:处理客户端请求,维护心跳
选举过程:
- 跟随者选举超时转为候选人
- 候选人发起投票请求
- 获得多数投票成为领导者
- 领导者定期发送心跳维持地位
日志复制机制:
- 领导者接收客户端请求,添加日志条目
- 复制日志条目到跟随者
- 多数节点复制成功后提交日志
- 通知跟随者应用日志到状态机
6.2 Paxos 协议原理
核心角色:
- 提议者:提出一致性问题的节点
- 接受者:处理提议的节点
- 投票者:决定提议是否有效的节点
Basic Paxos 流程:
准备阶段:
- 提议者选择唯一递增提案编号
- 向所有接受者发送准备请求
- 接受者承诺不再接受更小编号提案
接受阶段:
- 提议者收到多数响应后确定提议值
- 选择最大编号提案中的值或自有值
- 向接受者发送接受请求
学习阶段:
- 提议者收到多数接受响应
- 提案达成共识
- 学习者获知共识值
6.3 Raft vs Paxos 对比
特性 | Raft | Paxos |
---|---|---|
理解难度 | 容易 | 困难 |
实现复杂度 | 简单 | 复杂 |
领导选举 | 明确机制 | 无明确机制 |
日志复制 | 明确流程 | 理论性强 |
工程应用 | 广泛 | 学术研究 |
6.4 Etcd 中的 Raft 实现
Etcd Raft 特性:
- 优化选举:预投票机制避免分区脑裂
- 日志压缩:定期快照减少日志存储
- 流水线复制:提高日志复制效率
- 读写流程:
- 写请求:领导者通过 Raft 日志复制
- 读请求:支持线性化读和串行化读
集群配置:
# etcd 集群配置示例
name: etcd-node1
data-dir: /var/lib/etcd
listen-client-urls: http://0.0.0.0:2379
advertise-client-urls: http://node1:2379
listen-peer-urls: http://0.0.0.0:2380
initial-advertise-peer-urls: http://node1:2380
initial-cluster: etcd-node1=http://node1:2380,etcd-node2=http://node2:2380
initial-cluster-state: new
initial-cluster-token: etcd-cluster
7. 分布式系统设计原则
7.1 设计考量要点
一致性选择:
- 根据业务需求选择强一致性或最终一致性
- 权衡性能和数据准确性的需求
容错设计:
- 考虑节点故障、网络分区的处理
- 设计重试机制和故障转移策略
扩展性:
- 支持水平扩展和垂直扩展
- 设计无状态服务便于扩展
监控运维:
- 完善的监控和日志系统
- 自动化运维和故障恢复
7.2 最佳实践建议
分布式锁使用:
- 高性能场景使用 Redis
- 强一致性要求时选择 Etcd
- 设置合理的锁超时时间
事务方案选择:
- 高并发场景选择 TCC 或消息队列
- 强一致性要求选择 2PC
- 长业务流程选择 Saga
限流策略:
- 入口层统一限流
- 根据业务特性选择合适的限流算法
- 设置合理的限流阈值
Etcd 使用建议:
- 生产环境至少 3 节点集群
- 合理设置租约 TTL 时间
- 使用 Watch 机制实现事件驱动
- 定期备份关键数据