单机能搞定的事很少上分布式;一旦多机、多服务、网络不可靠,就要谈 CAP、一致性、幂等与故障模型。本篇是后端多篇的总纲,细节链到各专篇。
为什么难
| 假设被打破 | 后果 |
|---|
| 网络会丢包、延迟 | 超时、重复、乱序 |
| 节点会挂 | 部分失败、脑裂 |
| 没有全局时钟 | 顺序与「最新」难定义 |
| 并发 | 竞态、 lost update |
CAP 与 PACELC
CAP:Consistency、Availability、Partition tolerance——分区发生时 C 和 A 只能偏一方(P 在网络分布式里逃不掉)。
| 倾向 | 例子 |
|---|
| CP | 强一致配置、部分 ZooKeeper 场景 |
| AP | 可用优先 + 最终一致(很多缓存、DNS) |
PACELC:无分区时 Latency vs Consistency 的权衡——更贴近日常。
面试:别背「三选二」口号,要说清业务在分区下要保什么。
一致性级别
| 级别 | 直觉 |
|---|
| 强一致 | 读后必见最新写(同会话或全局) |
| 最终一致 | 暂时不一致,收敛到相同 |
| 因果一致 | 有因果关系的操作顺序保证 |
| 手段 | 说明 |
|---|
| 单主写入 | 写主库,读主或容忍从库延迟 |
| 分布式事务 | 2PC 重、TCC/Saga 业务侵入 |
| 事件驱动 | Outbox + Kafka 异步对齐 |
同一请求执行多次 = 执行一次的效果。
| 层 | 做法 |
|---|
| API | Idempotency-Key |
| DB | 唯一索引、UPSERT、UPDATE ... WHERE version=? |
| MQ | 消费端去重表、业务状态机 |
分布式 ID
| 方案 | 特点 |
|---|
| UUID | 简单;无序、索引局部性差 |
| 雪花 Snowflake | 时间 + 机器 + 序列;时钟回拨要处理 |
| DB 号段 | 批量取号;依赖 DB |
| Redis INCR | 快;要持久与高可用 |
复制与共识(点到为止)
| 概念 | 说明 |
|---|
| 主从复制 | MySQL/PG/Redis/Kafka 都有;异步有延迟 |
| 多主 | 冲突解决难 |
| Raft / Paxos | 选主 + 日志复制;etcd、部分 MQ 元数据 |
不必手推公式,能说 「选主、日志、多数派」 即可。
故障模型
| 类型 | 应对 |
|---|
| 超时 | 设 deadline、重试要有上限 |
| 重试 | 仅对幂等或安全操作;指数退避 |
| 部分失败 | 补偿、Saga、对账 |
| 级联 | 熔断、隔离舱 |
常见误解
- 「分布式 = 微服务」——多实例 + DB 主从已是分布式
- 「最终一致 = 不管一致」——要有收敛路径与业务容忍度
- 「加机器就线性扩展」——瓶颈在 DB、热点、协调开销
面试速记
- CAP 怎么说? 分区下 C/A 权衡;举例 CP/AP。
- 最终一致怎么实现? 异步复制、消息、对账、幂等。
- 幂等为什么重要? 重试、重复投递、双提交。
- 雪花 ID 注意什么? 机器 id、时钟回拨、趋势递增。
- 和单机最大区别? 部分失败是常态,设计要默认会失败。