外观
分布式系统理论 速查卡
🎯 覆盖 14 题 | ⭐ 高频 8 题 | 预计扫描 9 分钟 📌 先看⭐一句话答案 → 展开要点 → 自测清单检验
一、基础理论
知识地图:CAP(P必选,CP/AP权衡) → BASE(最终一致性=AP实践) → 一致性模型(强→顺序→因果→读己所写→单调读→最终)
⭐ CAP 定理
一句话: 分布式系统不能同时满足 C(一致性)、A(可用性)、P(分区容错);P 是必选项(网络分区不可避免),实际是在 CP 和 AP 之间权衡。
| 特性 | 含义 |
|---|---|
| C 一致性 | 所有非故障节点读到同一份最新数据 |
| A 可用性 | 所有非故障节点都能在合理时间内响应 |
| P 分区容错 | 网络分区时系统仍能对外服务 |
核心矛盾: 网络分区发生时,节点 B 收不到节点 A 的最新写入 → B 要么拒绝响应(保C弃A=CP) → 要么返回旧数据(保A弃C=AP)
常见系统 CAP 选择:
| 系统 | 选择 | 说明 |
|---|---|---|
| ZooKeeper | CP | 选举期间不可用,保证数据一致 |
| Eureka | AP | P2P 复制,可能读到旧注册表 |
| Nacos | AP+CP 可切换 | 临时实例 AP(Distro),持久实例 CP(Raft) |
| etcd | CP | 基于 Raft,写入需多数确认 |
| Redis Sentinel | AP | 异步复制,主从切换可能丢数据 |
⭐ BASE 理论
一句话: BASE 是 CAP 中 AP 方案的工程实践——放弃强一致,用 基本可用 + 软状态 + 最终一致性 换高可用;与 ACID 是对立面。
| 缩写 | 含义 |
|---|---|
| BA(Basically Available) | 故障时允许降级(响应变慢/部分功能不可用) |
| S(Soft State) | 允许中间状态,各副本数据可暂时不同步 |
| E(Eventually Consistent) | 经过一段时间后数据最终一致 |
ACID vs BASE:
| 维度 | ACID | BASE |
|---|---|---|
| 一致性 | 强一致(事务提交立即生效) | 最终一致(允许延迟) |
| 可用性 | 低(加锁等待) | 高(异步无锁) |
| 中间状态 | 不允许(原子性) | 允许(软状态) |
| 典型场景 | MySQL 事务 | 电商订单/消息队列 |
一致性模型(由强到弱)
| 模型 | 含义 | 典型实现 |
|---|---|---|
| 强一致(Linearizability) | 写入后所有读都返回最新值 | ZK/etcd |
| 顺序一致(Sequential) | 所有节点看到相同操作顺序 | 全序广播 |
| 因果一致(Causal) | 有因果关系的操作保序 | MongoDB Session |
| 读己所写 | 自己写的自己能立即读到 | 主从+强制读主 |
| 单调读 | 不会读到比之前更旧的数据 | 固定路由同一副本 |
| 最终一致(Eventual) | 停写后最终收敛一致 | Redis 主从/DNS/Eureka |
二、分布式共识
知识地图:Raft(选举+日志复制,etcd/Consul) → Paxos(理论更通用,工程难) → ZAB(ZK专用,epoch+ZXID)
⭐ Raft 算法
一句话: 选出一个 Leader 统一管理日志复制;选举靠 随机超时 → Candidate → 多数投票;日志复制靠 AppendEntries → 多数 ACK → commit。
三种角色: Follower(被动接收) → Candidate(竞选) → Leader(统一写入+心跳)
Leader 选举流程:
Follower 的 election timeout 到期(随机 150~300ms)
→ 变 Candidate, term+1, 投自己, 发 RequestVote
→ 其他节点判断: term够新 + 本任期未投票 + 日志不比自己旧 → 投 YES
→ 获超过半数票 → 成为 Leader → 立即发心跳
→ 随机超时减少 Split Vote日志复制流程:
客户端写 → Leader 追加本地日志(uncommitted)
→ AppendEntries RPC 发给所有 Follower
→ Follower 匹配 prevLogIndex/Term → ACK
→ 超过半数 ACK → commit → 应用状态机 → 响应客户端
→ 后续心跳携带 leaderCommit → Follower 也提交脑裂处理: 5节点分区[A,B]和[C,D,E] → [A,B]写入无法获半数ACK失败 → [C,D,E]选出新Leader → 网络恢复后A发现更高term退为Follower
Paxos vs Raft
| 维度 | Paxos | Raft |
|---|---|---|
| 领导者 | 无强制Leader,任何节点可Propose | 强Leader,所有写经Leader |
| 日志顺序 | 允许空洞 | 严格顺序追加 |
| 理解难度 | 极难 | 刻意易懂(选举+日志复制) |
| 工程落地 | 各实现差异大 | 实现统一(etcd/Consul/TiKV) |
ZAB vs Raft
| 维度 | ZAB(ZooKeeper) | Raft |
|---|---|---|
| 选举 | 选最大 ZXID 节点 | 随机超时+多数投票 |
| 任期 | epoch | term |
| 日志ID | ZXID(epoch+counter,64位) | term+logIndex |
| 模式 | 恢复模式(选举+同步) / 广播模式 | 无显式模式切分 |
| 同步 | DIFF/TRUNC/SNAP 专门同步阶段 | AppendEntries 逐步对齐 |
相同点: Leader-based + Quorum 多数确认 + 已提交不丢失 + 心跳检测
三、分布式事务
知识地图:2PC(Prepare→Commit,阻塞+单点) → 3PC(+CanCommit+超时) → TCC(业务层Try/Confirm/Cancel) → Seata(AT/TCC/Saga) → 本地消息表+MQ(最终一致)
⭐ 2PC / 3PC
一句话: 2PC = 协调者统一调度 Prepare→Commit,问题是 同步阻塞 + 单点故障 + 脑裂;3PC 加了 CanCommit 预询问 + 参与者超时自动提交,减少阻塞但仍有不一致风险。
2PC 流程:
阶段1 Prepare: 协调者→参与者「能否提交?」
参与者执行SQL+写redo/undo log+锁资源(不提交) → 返回YES/NO
阶段2 Commit: 全YES → Commit → 释放资源
任一NO/超时 → Rollback → undo log回滚2PC 四大问题:
| 问题 | 说明 |
|---|---|
| 同步阻塞 | 参与者锁定资源等协调者指令 |
| 单点故障 | 协调者挂了,参与者一直阻塞 |
| 脑裂 | 部分参与者收到Commit提交了,部分没收到 |
| 过于保守 | 任一失败就全部回滚 |
3PC 改进: +CanCommit(不锁资源预检) + 参与者超时自动提交(走到PreCommit说明都同意了)
⭐ TCC 模式
一句话: 业务层分布式事务——Try(预留资源) → Confirm(确认提交) → Cancel(释放资源);必须处理三大问题:幂等 + 空回滚 + 悬挂。
转账案例(A→B转100):
Try: A冻结100(frozen+=100) B创建待入账(pending+=100)
Confirm: A扣减(balance-=100) B入账(balance+=100)
Cancel: A解冻(frozen-=100) B删除待入账(pending-=100)三大注意事项:
| 问题 | 说明 | 解决 |
|---|---|---|
| 幂等 | Confirm/Cancel可能被重试多次 | 事务状态表记录执行状态,已执行则直接返回 |
| 空回滚 | Cancel时Try还没执行(网络延迟) | Cancel检测Try未执行→插入CANCELLED记录→返回成功 |
| 悬挂 | 空回滚后迟到的Try才到达 | Try先检查是否已Cancel→已Cancel则拒绝Try |
⭐ Seata AT / TCC / Saga 对比
一句话: AT 无侵入(undo_log自动回滚)适合常规CRUD;TCC 性能最高适合金融场景;Saga 适合长事务跨多服务编排。
| 维度 | AT 模式 | TCC 模式 | Saga 模式 |
|---|---|---|---|
| 侵入性 | 无(@GlobalTransactional) | 高(手写Try/Confirm/Cancel) | 中(需写补偿方法) |
| 性能 | 中(写undo_log+全局锁) | 高(无undo_log无全局锁) | 高(无全局锁) |
| 隔离性 | 全局锁保证 | 业务自行保证 | 无隔离性 |
| 回滚 | 自动(before image反向SQL) | 手动(Cancel) | 手动(补偿事务) |
| 场景 | 订单+库存+积分 | 转账/支付/预扣款 | 旅行预订(酒店+机票+租车) |
四、分布式基础设施
知识地图:分布式ID(Snowflake 1+41+10+12) → 一致性哈希(hash ring+虚拟节点) → 分布式Session(Redis集中存储) → 分布式锁(Redis/ZK/MySQL)
⭐ Snowflake 雪花算法
一句话: 64位Long型ID = 1位符号(0) + 41位时间戳(69年) + 10位机器ID(1024台) + 12位序列号(4096/ms);单机理论 QPS 约 409.6 万/秒。
0 | 41位时间戳(毫秒级,~69年) | 5位数据中心+5位机器 | 12位序列号分布式ID方案对比:
| 方案 | 优点 | 缺点 |
|---|---|---|
| UUID | 本地生成,全球唯一 | 无序(B+树性能差),太长 |
| DB自增 | 简单有序 | 单点瓶颈,分库后不唯一 |
| Redis INCR | 高性能有序 | 依赖Redis可用性 |
| Snowflake | 本地生成,有序,高性能 | 时钟回拨问题 |
时钟回拨解决: 抛异常(简单) / 等待追上(小幅回拨) / 扩展位(预留回拨序号)
业界方案: Leaf(美团,号段+Snowflake双模式) / uid-generator(百度,RingBuffer预生成) / Tinyid(滴滴,号段+多DB)
⭐ 一致性哈希
一句话: 将哈希空间组成环(0~2^32-1),节点和key都映射到环上,key 顺时针找到第一个节点即为归属;增删节点只影响相邻区间。用 虚拟节点(150~200个/物理节点) 解决数据倾斜。
传统 hash(key)%N → N变则几乎所有key重映射 → 缓存雪崩
一致性哈希:
节点/key 都映射到 0~2^32 的环上
key 顺时针找第一个节点 → 增删节点只影响相邻一段
虚拟节点: 每个物理节点映射150+虚拟节点 → 分布均匀应用: 缓存集群分片 / Nginx consistent_hash / Cassandra&Dynamo / CDN节点选择
补充速览
| 关键词 | 核心答案 |
|---|---|
| 一致性模型选择 | 余额→强一致; 订单状态→最终一致(本地消息表+MQ); 用户信息→读己所写(写主读主) |
| Paxos | Prepare+Accept两阶段; 无强制Leader; 理论强但工程难 |
| ZAB | ZK专用; 恢复模式(选举+DIFF/TRUNC/SNAP同步)+广播模式; ZXID=epoch+counter |
| 本地消息表+MQ | 业务SQL+插消息同一事务→异步发MQ→消费者幂等处理→定时任务重试未发送消息 |
| 分布式Session | 粘性Session(ip_hash,宕机丢失) / Session复制(O(N^2)不扩展) / Redis集中存储(推荐) / JWT无状态 |
| 分布式锁对比 | Redis(性能最高,10万QPS,可能丢锁) / ZK(强一致,临时节点+心跳) / MySQL(最简单,性能最低) |
| Redisson | 可重入+看门狗续期(30s,10s一次)+公平锁; RedLock解决主从切换丢锁(有争议) |
| ZK分布式锁 | 临时顺序节点+Watch前一个节点; 天然公平+无需设过期时间+避免惊群 |
🧠 助记汇总
| 口诀 | 含义 |
|---|---|
| P必选,CA二选一 | CAP: P是前提,实际是CP vs AP |
| 基软终 | BASE: 基本可用/软状态/最终一致 |
| 随投半心 | Raft选举: 随机超时→投票→半数通过→心跳维持 |
| 追半提 | Raft日志复制: 追加→半数ACK→提交 |
| 准提 | 2PC: Prepare→Commit; 问题:阻塞+单点+脑裂 |
| 试确消 | TCC: Try/Confirm/Cancel |
| 幂空悬 | TCC三大问题: 幂等/空回滚/悬挂 |
| 1-41-10-12 | Snowflake: 符号位+时间戳+机器ID+序列号 |
| 环顺虚 | 一致性哈希: 哈希环+顺时针找节点+虚拟节点 |
✅ 自测清单
| # | 问题 | 你能说出... |
|---|---|---|
| 1 | CAP 定理 | 三个特性含义 + 为什么P必选 + ZK/Eureka/Nacos的选择 |
| 2 | BASE 理论 | BA/S/E含义 + ACID vs BASE对比 + 电商案例 |
| 3 | 一致性模型 | 六种模型由强到弱 + 各自典型实现 |
| 4 | Raft 选举 | 随机超时→Candidate→RequestVote→多数票→Leader |
| 5 | Raft 日志复制 | AppendEntries→Follower匹配→多数ACK→commit |
| 6 | 2PC / 3PC | 2PC流程+四大问题 + 3PC改进点(预询问+超时) |
| 7 | TCC | Try/Confirm/Cancel + 幂等/空回滚/悬挂处理 |
| 8 | Seata 三模式 | AT(无侵入)/TCC(高性能)/Saga(长事务) 各自场景 |
| 9 | Snowflake | 1+41+10+12 结构 + 时钟回拨解决方案 |
| 10 | 一致性哈希 | 哈希环原理 + 为什么需要虚拟节点 + 应用场景 |
| 11 | 分布式锁 | Redis/ZK/MySQL 三方案优缺点对比 |
| 12 | 分布式Session | 四种方案 + 为什么推荐Redis集中存储 |
💡 首次全部过一遍 → 第2天只过答不上来的 → 第4天再复习 → 面试前一天最后扫一遍