分布式系统入门
分布式系统是系统设计面试的核心。关键不是背概念,而是理解CAP 为什么不能同时满足,以及如何在实际场景中做权衡。
面试考察点
面试官通过这道题想考察:
1. 你是否理解 CAP 定理的本质
2. 你是否能解释一致性哈希的原理
3. 你是否理解分布式事务的挑战
4. 你是否有分布式系统的实战经验
一、CAP 定理
1.1 CAP 是什么?(小白解释)
面试官追问:"什么是 CAP?为什么不能同时满足?"
CAP = Consistency + Availability + Partition Tolerance
C - 一致性:所有节点看到相同的数据
A - 可用性:每个请求都能收到响应
P - 分区容错:系统能容忍网络分区
为什么不能同时满足?
假设系统有 A、B 两个节点,网络断开了(分区)
场景:客户端向 A 写入数据,B 同步失败
选项:
1. 牺牲可用性 → 等 B 同步完再响应 → 不满足 A
2. 牺牲一致性 → A 直接响应,B 还是旧数据 → 不满足 C
3. 牺牲分区容错 → 不可能,网络断开了就是断开了 → 不满足 P
现实:网络分区不可避免!
所以实际上只能在 C 和 A 之间权衡!
1.2 CP vs AP(面试核心)
┌─────────────────────────────────────────────────┐
│ CAP 选择 │
├─────────────────────────────────────────────────┤
│ │
│ CP 系统(强一致): │
│ - 牺牲可用性 │
│ - 网络分区时可能不可用 │
│ - 代表:Zookeeper、etcd │
│ - 适合:银行、金融、分布式锁 │
│ │
│ AP 系统(高可用): │
│ - 牺牲一致性 │
│ - 网络分区时仍可用,但数据可能不一致 │
│ - 代表:Cassandra、DynamoDB │
│ - 适合:社交 Feed、评论、推荐 │
│ │
│ 面试加分点: │
│ "CAP 不是三选一,P 是必须满足的, │
│ 所以实际上是在 C 和 A 之间权衡" │
│ │
└─────────────────────────────────────────────────┘
1.3 实际例子
实际系统如何选择 CAP:
1. 银行转账(CP)
- 转账必须强一致
- 分区时宁可不可用,也不能出错
2. 社交 Feed(AP)
- 用户发一条动态
- 分区时其他用户可能暂时看不到
- 但不能说系统挂了
3. 分布式锁(CP)
- 锁必须是一致性的
- 不能出现两把锁同时生效
二、一致性哈希
2.1 为什么需要一致性哈希?
面试官追问:"为什么需要一致性哈希?普通哈希有什么问题?"
普通哈希的问题:
假设 3 台服务器:hash(key) % 3
数据分布:
- key1 % 3 = 1 → 服务器 1
- key2 % 3 = 2 → 服务器 2
- key3 % 3 = 0 → 服务器 3
问题:添加新服务器 4 时
hash(key) % 4 → 几乎所有数据的服务器位置都变了!
影响:
- 所有数据都要重新分配
- 缓存全部失效
- 雪崩!
解决方案:一致性哈希!
2.2 一致性哈希的原理
一致性哈希环:
0°
↑
270°───┼───90°
│
↓
180°
把服务器和数据都映射到环上:
- 数据沿环顺时针找最近的服务器
- 添加/删除服务器时,只有相邻的数据要移动
为什么叫"一致性"?
因为添加/删除服务器时,只有相邻的数据要重新分配
其他大部分数据不受影响!
虚拟节点:
- 一台物理服务器对应多个虚拟节点
- 让数据分布更均匀
2.3 面试能加分的回答
"一致性哈希通过把数据映射到环上,
使得添加/删除服务器时,只有相邻的数据要移动,
其他数据不受影响,大大减少了数据迁移量"
三、分布式事务
3.1 什么是分布式事务?
面试官追问:"为什么分布式事务这么难?"
分布式事务 = 多个节点上的操作要同时成功或失败
挑战:
- 网络可能延迟
- 节点可能故障
- 不同节点的操作在不同机器上执行
类比:
把书从北京送到上海
- 北京的书要发出
- 上海的仓库要接收
- 中间任何一个环节都可能出问题
集中式系统:一个数据库能保证 ACID
分布式系统:每个节点只能保证本地事务
3.2 两阶段提交(2PC)
两阶段提交:
阶段 1 - 准备:
协调者 → 所有参与者:准备好提交了吗?
← 参与者1:准备好了(锁定资源)
← 参与者2:准备好了(锁定资源)
阶段 2 - 提交:
协调者 → 所有参与者:提交!
← 参与者1:提交完成
← 参与者2:提交完成
问题:
1. 协调者是单点故障
2. 参与者锁定资源期间,其他事务无法访问
3. 如果某个参与者在第二阶段超时,不知道是提交还是回滚
3.3 TCC 和 Saga
TCC(Try-Confirm-Cancel):
Try:预留资源(冻结)
Confirm:确认使用
Cancel:释放资源
Saga:
把长事务分解成多个本地事务
每个步骤都有对应的补偿事务
A → B → C → D
失败时:C_compensate → B_compensate → A_compensate
适用于长事务,不用锁定资源
但需要每个步骤都支持补偿
四、面试总结
分布式系统核心
┌─────────────────────────────────────────────────┐
│ 分布式系统核心 │
├─────────────────────────────────────────────────┤
│ │
│ CAP 定理: │
│ - P 必须满足,实际是 C 和 A 的权衡 │
│ │
│ 一致性哈希: │
│ - 解决数据迁移问题 │
│ - 环结构 + 虚拟节点 │
│ │
│ 分布式事务: │
│ - 2PC:强一致,但有单点和阻塞问题 │
│ - TCC/Saga:最终一致,更灵活 │
│ │
└─────────────────────────────────────────────────┘
面试能加分的回答
1. 能解释 CAP
"CAP 中 P 是必须满足的,网络分区不可避免,
所以实际上是在一致性和可用性之间权衡"
2. 能解释一致性哈希
"一致性哈希通过环结构,让添加/删除服务器时
只有相邻数据要移动,大大减少数据迁移"
3. 能权衡不同方案
"这个场景下,我选择 AP 方案,因为用户可以容忍短暂不一致"