Skip to content

分布式系统理论 速查卡

🎯 覆盖 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 选择:

系统选择说明
ZooKeeperCP选举期间不可用,保证数据一致
EurekaAPP2P 复制,可能读到旧注册表
NacosAP+CP 可切换临时实例 AP(Distro),持久实例 CP(Raft)
etcdCP基于 Raft,写入需多数确认
Redis SentinelAP异步复制,主从切换可能丢数据

⭐ BASE 理论

一句话: BASE 是 CAP 中 AP 方案的工程实践——放弃强一致,用 基本可用 + 软状态 + 最终一致性 换高可用;与 ACID 是对立面。

缩写含义
BA(Basically Available)故障时允许降级(响应变慢/部分功能不可用)
S(Soft State)允许中间状态,各副本数据可暂时不同步
E(Eventually Consistent)经过一段时间后数据最终一致

ACID vs BASE:

维度ACIDBASE
一致性强一致(事务提交立即生效)最终一致(允许延迟)
可用性低(加锁等待)高(异步无锁)
中间状态不允许(原子性)允许(软状态)
典型场景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

维度PaxosRaft
领导者无强制Leader,任何节点可Propose强Leader,所有写经Leader
日志顺序允许空洞严格顺序追加
理解难度极难刻意易懂(选举+日志复制)
工程落地各实现差异大实现统一(etcd/Consul/TiKV)

ZAB vs Raft

维度ZAB(ZooKeeper)Raft
选举选最大 ZXID 节点随机超时+多数投票
任期epochterm
日志IDZXID(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); 用户信息→读己所写(写主读主)
PaxosPrepare+Accept两阶段; 无强制Leader; 理论强但工程难
ZABZK专用; 恢复模式(选举+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-12Snowflake: 符号位+时间戳+机器ID+序列号
环顺虚一致性哈希: 哈希环+顺时针找节点+虚拟节点

✅ 自测清单

#问题你能说出...
1CAP 定理三个特性含义 + 为什么P必选 + ZK/Eureka/Nacos的选择
2BASE 理论BA/S/E含义 + ACID vs BASE对比 + 电商案例
3一致性模型六种模型由强到弱 + 各自典型实现
4Raft 选举随机超时→Candidate→RequestVote→多数票→Leader
5Raft 日志复制AppendEntries→Follower匹配→多数ACK→commit
62PC / 3PC2PC流程+四大问题 + 3PC改进点(预询问+超时)
7TCCTry/Confirm/Cancel + 幂等/空回滚/悬挂处理
8Seata 三模式AT(无侵入)/TCC(高性能)/Saga(长事务) 各自场景
9Snowflake1+41+10+12 结构 + 时钟回拨解决方案
10一致性哈希哈希环原理 + 为什么需要虚拟节点 + 应用场景
11分布式锁Redis/ZK/MySQL 三方案优缺点对比
12分布式Session四种方案 + 为什么推荐Redis集中存储

💡 首次全部过一遍 → 第2天只过答不上来的 → 第4天再复习 → 面试前一天最后扫一遍