分布式系统
面试权重:★★★ | 适用级别:P7/P8+ | 预计复习时间:2周
概览
面试权重:★★★ | 适用级别:P7/P8+ | 预计复习时间:2周
这一章的重点不是把所有理论都背成学术定义,而是能把 CAP、共识、分布式事务、分布式锁、全局 ID、限流这些点落到真实业务取舍上。
建议用法
复习时建议按"系统为什么不能像单机那样简单、出问题时最容易在哪里失控、你会怎么做取舍"三条线去看。这样遇到系统设计和项目深挖时更容易接上话。
一、知识体系
1. 分布式理论基础 ★★★
1.1 CAP定理 ★★★
CAP 真正考什么
- 核心结论
- CAP 不是让你在平时三选二,而是在网络分区发生时,系统必须在一致性和可用性之间做取舍。
- 原理展开
- P 在分布式系统里几乎不可避免,所以真正可选的是 C 和 A。
- CP 系统更愿意牺牲部分可用性,保证一致视图,比如 Zookeeper、etcd。
- AP 系统更愿意在分区期继续响应,再通过异步方式走向最终一致,比如 Eureka、很多缓存和 KV 系统。
- 面试怎么答
- "CAP 讲的是分区故障下的取舍,不是说系统平时永远只能做到两项。很多候选人会把这个边界说模糊。"
- 易错点
- 不要把"一致性"答成数据库 ACID 里的应用级一致性,这里更偏分布式可见性一致。
1.2 BASE理论 ★★
- 核心结论
- BASE 是很多 AP 系统的工程落地思路,强调基本可用、软状态、最终一致。
- 原理展开
- 为了换取高可用,系统允许短暂不一致,再通过重试、补偿、对账、异步同步收敛。
- 面试怎么答
- "业务系统大多数时候不是追求绝对实时一致,而是追求可控最终一致,这就是 BASE 在工程里的价值。"
1.3 一致性模型 ★★
- 核心结论
- 强一致、顺序一致、因果一致、最终一致要知道大致差别,面试里更重要的是能把它们和业务容忍度对应起来。
- 应用理解
- 支付扣款这类核心状态更靠近强一致诉求。
- 通知、积分、搜索索引这类更适合最终一致。
2. 分布式共识算法 ★★
2.1 Paxos ★
- 一句话结论
- Paxos 理论地位很高,但工程面试里通常只要求知道它解决"多数派下的一致决议"问题。
2.2 Raft ★★★
为什么工程里更常讲 Raft
- 核心结论
- Raft 把共识问题拆成更容易理解的 leader 选举、日志复制和安全性约束,因此比 Paxos 更适合工程实践和面试表达。
- 原理展开
- 节点状态通常分为 Follower、Candidate、Leader。
- 通过随机选举超时减少同时竞选造成的冲突。
- Leader 负责日志复制,只有被多数节点确认的日志才算提交。
- 面试怎么答
- "Raft 的关键不是会背状态名,而是知道为什么要有任期、为什么要多数派、为什么旧 leader 不能随便把日志写成已提交。"
- 常见追问
- 为什么多数派能保证一致性?
- 网络分区时会发生什么?
2.3 ZAB协议 ★★
- 核心结论
- ZAB 是 Zookeeper 为主从广播语义设计的协议,更贴近协调服务场景。
- 补充说明
- 回答时知道它包含崩溃恢复和消息广播两个模式即可,不必硬背所有流程细节。
3. 分布式事务 ★★★
3.1 2PC(两阶段提交) ★★
- 核心结论
- 2PC 能提供较强一致,但同步阻塞、协调者单点和恢复复杂度高,是典型理论可行、业务代价偏重的方案。
- 面试怎么答
- "2PC 最大的问题不是慢一点,而是协调者和参与者都容易被长时间锁住,业务吞吐和可用性都受影响。"
3.2 3PC(三阶段提交) ★
- 一句话结论
- 3PC 通过引入超时和预提交试图降低阻塞,但它仍然无法真正解决网络分区下的不一致风险。
3.3 TCC(Try-Confirm-Cancel) ★★★
TCC 什么时候值得用
- 核心结论
- TCC 适合高价值、流程短、资源边界清晰且业务能接受较强改造的场景。
- 原理展开
- Try 先预留资源,Confirm 正式提交,Cancel 做补偿释放。
- 它本质上把事务控制显式交给业务,因此性能和控制力较强,但侵入性也最大。
- 面试怎么答
- "TCC 不是分布式事务通用解,它更适合核心交易链路。因为它要求业务明确知道怎样预留、确认和补偿。"
- 易错点
- TCC 一定要强调幂等、防悬挂、空回滚、重复确认这些工程问题。
3.4 Saga模式 ★★
- 核心结论
- Saga 适合长流程事务,把大事务拆成本地事务序列,失败时按逆序补偿。
- 原理展开
- 编排式由中心协调流程,协作式通过事件驱动让各服务自己响应。
- 面试怎么答
- "如果流程长、链路跨多个服务且不适合预留资源,Saga 往往比 TCC 更自然,但补偿设计会更复杂。"
3.5 本地消息表 ★★★
- 核心结论
- 本地消息表是业务里非常常见的最终一致方案,因为它简单、稳定、容易治理。
- 原理展开
- 在本地事务里同时写业务数据和消息表,再由后台任务或 MQ 异步投递。
- 只要保证消息表可靠落库,就能通过重试把消息最终发出去。
- 面试怎么答
- "很多业务其实用不到 TCC 或 Seata,本地消息表加幂等消费已经能很好解决最终一致问题。"
3.6 最大努力通知 ★
- 一句话结论
- 对一致性要求不高、允许人工兜底的场景,可用多次重试 + 告警形成最大努力通知。
3.7 Seata框架 ★★★
- 核心结论
- Seata 提供 AT、TCC、Saga、XA 多种模式,但面试里最常问的是 AT 模式原理和适用边界。
- 原理展开
- AT 模式通过拦截 SQL、记录前后镜像和 undo log 实现自动补偿。
- 优点是业务侵入相对小,缺点是热点写场景下全局锁和回滚成本会成为瓶颈。
- 面试怎么答
- "Seata AT 适合改造成本敏感的业务,但别把它当银弹。碰到热点行、高并发扣减类场景时要格外谨慎。"
4. 分布式锁 ★★★
4.1 基于Redis ★★★
- 核心结论
- Redis 锁性能最好、实现最轻,但可靠性和严格时序语义不是最强。
- 原理展开
- 标准写法是
SET key value NX EX加唯一标识,再用 Lua 做 compare-and-delete。 - 主从切换、锁超时、业务执行过长都可能带来锁安全风险。
- Redisson 在工程落地上更成熟,提供续期、可重入、公平锁等能力。
- 标准写法是
- 面试怎么答
- "Redis 锁适合高并发场景下的大多数工程协作,但如果业务要求强一致和 fencing token,就别勉强。"
4.2 基于Zookeeper ★★
- 核心结论
- ZK 锁可靠性更强,适合强协调场景,但吞吐和复杂度都不如 Redis 锁轻。
- 原理展开
- 临时顺序节点天然支持有序等待和会话失效自动释放。
4.3 基于MySQL ★
- 一句话结论
- MySQL 锁实现简单,但性能和鲁棒性通常不是首选,更多作为兜底或小规模场景方案。
4.4 分布式锁对比与选型
- 选型建议
- 高并发、对极致性能更敏感:优先 Redis。
- 强一致、强调协调正确性:优先 ZK/etcd。
- 简单系统、无额外基础设施:可短期使用 MySQL。
5. 分布式ID ★★★
5.1 UUID
- 一句话结论
- UUID 全局唯一很方便,但无序、长度大、对数据库索引不友好。
5.2 数据库自增
- 核心结论
- 数据库自增最直观,但单点与吞吐瓶颈明显,所以通常要配合号段模式演进。
5.3 Snowflake算法 ★★★
Snowflake 的结构与痛点
- 核心结论
- Snowflake 通过时间戳、机器号、序列号组合生成趋势有序的 64 位 ID,很适合高吞吐场景。
- 原理展开
- 最大风险是时钟回拨,因为时间戳是高位核心。
- 机器号分配、跨机房部署、时间同步都是工程重点。
- 面试怎么答
- "Snowflake 的优势是高性能和有序,但它不是没有代价,时钟回拨就是最典型风险。"
5.4 Leaf(美团)
- 一句话结论
- Leaf 兼顾了号段模式和 Snowflake 模式,属于国内业务里常被拿来对比的成熟方案。
5.5 Tinyid(滴滴)、UidGenerator(百度)
- 一句话结论
- 这些方案本质上也是围绕号段、趋势有序、机器号治理做工程增强。
6. 分布式缓存一致性 ★★
6.1 一致性Hash ★★★
- 核心结论
- 一致性 Hash 的核心价值是节点增减时尽量少迁移数据。
- 原理展开
- 环形空间和虚拟节点一起用,既减少迁移,又缓解数据倾斜。
- 面试怎么答
- "一致性 Hash 解决的是节点变化下的大规模搬迁问题,而不是所有分片问题都一定要靠它。"
6.2 数据分片策略
- 常见方案
- Hash 取模:简单但扩容成本高。
- 范围分片:适合按时间等维度,但容易热点。
- 一致性 Hash:扩缩容友好。
- 虚拟槽:像 Redis Cluster 这样更易治理。
7. 分布式限流 ★★
7.1 限流算法
- 核心结论
- 固定窗口实现简单但有边界突刺,滑动窗口更平滑,令牌桶最常用于允许突发的业务 API。
- 面试怎么答
- "如果业务允许短时突发,令牌桶通常比漏桶更合适;如果要严格匀速输出,漏桶更合适。"
7.2 分布式限流实现
- 常见方案
- Redis + Lua:最常见,易落地。
- Sentinel:治理能力完整,适合 Java 业务体系。
- 网关层限流:适合统一入口防护。
二、高频面试题
基础级(P7必答)
- CAP 理论是什么?CP 和 AP 系统分别举例说明。
- 30秒答法:CAP 讲的是网络分区发生时,系统必须在一致性和可用性之间做取舍。像 Zookeeper、etcd 更偏 CP;Eureka、很多缓存系统更偏 AP。
- 关键词:分区、CP、AP、一致性、可用性
- 追问提醒:为什么 P 不能放弃;和 ACID 的一致性区别
- 常见分布式事务方案有哪些?怎么选?
- 30秒答法:强一致方向有 2PC/XA,最终一致方向常见 TCC、Saga、本地消息表和 Seata AT。选型要看一致性要求、性能要求、业务改造成本和团队驾驭能力。
- 关键词:2PC、TCC、Saga、本地消息表、Seata
- 追问提醒:核心交易链路和非核心链路是否同一方案;补偿和幂等怎么做
- TCC 的原理是什么?Confirm 失败怎么办?
- 30秒答法:TCC 分 Try 预留、Confirm 提交、Cancel 回滚。Confirm 失败后要能重复重试,并保证幂等;最终仍失败则需要告警和人工干预。
- 关键词:预留、确认、取消、幂等、补偿
- 追问提醒:空回滚、悬挂、重复提交
- Redis 分布式锁怎么实现?Redisson 的看门狗机制是什么?
- 30秒答法:常见实现是
SET NX EX+ 唯一值 + Lua 释放。Redisson 会在业务持锁期间后台定期续期,避免锁在业务未完成时自动过期。 - 关键词:SET NX EX、唯一值、Lua、续期、看门狗
- 追问提醒:锁超时和主从切换风险;为什么还会丢锁
- Snowflake 算法的原理是什么?时钟回拨怎么处理?
- 30秒答法:Snowflake 用时间戳、机器号和序列号拼出趋势有序 ID。时钟回拨常见处理是等待时钟追上、拒绝服务或引入更稳的 workerId/时钟治理方案。
- 关键词:时间戳、机器号、序列号、时钟回拨
- 追问提醒:为什么趋势有序对数据库友好;号段模式和 Snowflake 对比
- 什么是一致性 Hash?虚拟节点解决了什么问题?
- 30秒答法:一致性 Hash 把节点映射到一个环上,数据落到顺时针第一个节点,增删节点时只迁移局部数据。虚拟节点是为了让数据分布更均匀,避免物理节点过少导致倾斜。
- 关键词:环、迁移量、虚拟节点、数据倾斜
- 追问提醒:和取模分片对比;什么时候用虚拟槽更合适
- 令牌桶和漏桶的区别是什么?
- 30秒答法:令牌桶按速率发放令牌,允许短时突发;漏桶按固定速率出水,更强调匀速输出。API 网关更常用令牌桶,严格平滑消费场景更偏漏桶。
- 关键词:令牌桶、漏桶、突发流量、匀速输出
- 追问提醒:滑动窗口;分布式限流落地
- Raft 的 Leader 选举过程是怎样的?
- 30秒答法:Follower 超时收不到心跳就转为 Candidate 发起投票,拿到多数票后成为 Leader,再负责日志复制。随机超时是为了避免多个节点反复同时竞选。
- 关键词:Follower、Candidate、Leader、多数票、随机超时
- 追问提醒:日志新旧判断;脑裂和双主是否可能
- BASE 理论和 CAP 的关系是什么?
- 30秒答法:BASE 可以看成很多 AP 系统的工程化实践,强调基本可用、软状态和最终一致。它告诉你在放弃强一致后,系统怎么靠补偿和异步机制活下来。
- 关键词:BASE、AP、最终一致、补偿
- 追问提醒:哪些业务不适合 BASE;最终一致怎么验证
- Seata AT 模式的原理是什么?
- 30秒答法:Seata AT 通过拦截 SQL 记录前后镜像和 undo log,本地事务先提交,分布式回滚时再用镜像补偿。优点是改造小,缺点是全局锁和热点写场景下性能压力大。
- 关键词:前后镜像、undo log、全局锁、补偿
- 追问提醒:为什么热点库存场景要谨慎;与 TCC 的取舍
进阶级(P8+深挖)
- 你通常怎么做分布式事务选型?
- 30秒答法:我会先区分核心链路和非核心链路。核心链路如果状态强依赖且流程短,可考虑 TCC;大多数场景优先本地消息表或 MQ 最终一致;改造成本敏感时才评估 Seata AT。
- 关键词:核心链路、最终一致、改造成本、性能
- 追问提醒:失败补偿;对账机制;业务幂等
- RedLock 的争议点是什么?你怎么看?
- 30秒答法:争议主要在网络抖动、GC 停顿、时钟漂移下锁语义不一定足够强。我的判断是非强一致场景可以用,但如果业务真的要求严格协调,就应该换更适合的协调系统。
- 关键词:RedLock、时钟漂移、GC 停顿、强一致
- 追问提醒:fencing token;ZK/etcd 对比
- 如何设计一个高可用的分布式 ID 服务?
- 30秒答法:通常会用号段模式或 Snowflake 变体,配合机房隔离、workerId 管理、时间同步监控和 SDK 本地缓存。关键不是把 ID 发出来,而是异常时还能稳定发、可观测、可降级。
- 关键词:号段、Snowflake、workerId、降级、可观测
- 追问提醒:双 buffer;时钟回拨治理;机房容灾
- 分布式系统里的 exactly-once 语义怎么理解?
- 30秒答法:严格意义的 exactly-once 很难,业务里更多是 at-least-once 加幂等消费,达到效果上的 exactly-once。重点是消息 ID、去重状态和幂等落地。
- 关键词:at-least-once、幂等、去重、效果一致
- 追问提醒:Kafka 事务;消费端幂等表
- API 网关层怎么做精确限流?
- 30秒答法:先按限流维度拆开,比如用户、接口、租户、IP,再在 Redis 或网关插件里用 Lua 实现原子判断与扣减。精确性越高,存储和计算成本越大,要结合业务容忍度做权衡。
- 关键词:网关、Redis、Lua、原子性、多维度限流
- 追问提醒:令牌桶实现;热点用户;降级策略
三、实战场景题(P8+重点)
- 订单服务扣款、扣库存、加积分,如何保证一致性?
- 回答框架
- 先区分核心和非核心动作。
- 核心动作如果必须强一致,再看是否值得 TCC/Seata。
- 非核心动作优先 MQ 最终一致或本地消息表。
- 补充幂等、补偿、对账、告警。
- 核心关注点:不要把所有动作都塞进一套强事务里。
- 秒杀库存扣减,Redis 锁和 ZK 锁怎么选?
- 回答框架
- 先看并发量和一致性要求。
- 高并发热点场景优先 Redis 锁或更激进的无锁设计。
- 真正强协调场景才考虑 ZK。
- 同时说明库存系统更常见的主线是预扣减、队列化、幂等校验,而不是只谈锁。
- 核心关注点:锁不是唯一解。
- 支付回调可能重复通知,如何设计幂等?
- 回答框架
- 业务主键或回调流水号唯一约束。
- 状态机只允许前进不允许回退。
- 成功后重复请求直接返回成功。
- 对账和告警做最终兜底。
- 核心关注点:业务幂等优先于中间件幻想。
- 设计日均十亿消息的全局 ID 方案
- 回答框架
- 明确有序性、唯一性、可用性和延迟目标。
- 主方案选 Snowflake 或号段模式。
- 再讲 workerId 分配、时钟回拨、机房隔离和 SDK 缓存。
- 核心关注点:吞吐、稳定性和运维成本要一起讲。
四、学习资源推荐
书籍
- 《数据密集型应用系统设计》:分布式系统方法论底座
- 《从Paxos到Zookeeper》:一致性协议和协调服务经典
- 《分布式系统概念与设计》:体系化补充读物
博客/文章
- Seata 官方文档:分布式事务落地细节
- Martin Kleppmann 博客:共识、锁、消息语义分析很有价值
- 各大厂技术博客中的分布式事务与分布式 ID 实战文章
视频
- 6.824 分布式系统课程
- 分布式事务与一致性实战专题课