🌐 第五章 · 分布式系统

分布式系统架构

本章涵盖CAP定理、分布式一致性协议、分布式事务、缓存架构和消息队列等核心考点,占综合知识考试7%-13%的分值。分布式系统是近年来的高频考点,需重点掌握。

7%-13%考试分值占比
8知识模块
★★★★★重要程度
15章节测验题
⚖️

CAP定理与BASE理论

⚖️CAP定理详解

CAP定理由Eric Brewer于2000年提出,是分布式系统设计的理论基础。它指出一个分布式系统不可能同时满足以下三个特性:

特性英文含义说明
C 一致性Consistency所有节点在同一时间看到的数据是相同的每次读操作都能读到最新的写操作结果。等同于线性一致性
A 可用性Availability每个请求都能在合理时间内收到非错误的响应不保证数据是最新的,但保证每次请求都有响应
P 分区容错性Partition Tolerance网络分区时系统仍能继续工作网络分区是必然存在的,分布式系统必须具备分区容错能力
🎯
核心结论(必考):在分布式系统中,P(分区容错性)是必然存在的,因为网络不可靠。因此系统只能在C(一致性)和A(可用性)之间做选择,不可能三者兼得。
CAP定理示意 — 三者最多取其二
C
一致性
A
可用性
P
分区容错
分布式系统中 P 必须满足,实际在 C 与 A 间权衡

🔄CP系统 vs AP系统

对比维度CP系统(一致性优先)AP系统(可用性优先)
选择保证一致性 + 分区容错性保证可用性 + 分区容错性
行为网络分区时拒绝部分请求以保证数据一致网络分区时继续响应,数据可能不一致
典型系统Zookeeper、HBase、etcdCassandra、Eureka、Dynamo
适用场景金融交易、选举系统社交网络、内容分发
一致性强一致性最终一致性

📋BASE理论

BA(Basically Available)基本可用:分布式系统在出现故障时,允许损失部分可用性,但保证核心功能可用。例如:电商大促时部分非核心服务降级
S(Soft State)软状态:允许系统中存在中间状态,该状态不影响系统整体可用性。例如:数据同步过程中的延迟
E(Eventually Consistent)最终一致性:经过一段时间后,系统中的所有数据副本最终会达到一致状态。不要求实时一致
💡
CAP与BASE的关系:BASE理论是对CAP中AP方案的延伸,是大规模分布式系统的工程实践总结。BASE用"基本可用+软状态+最终一致性"替代了传统的ACID强一致性要求。
🗳️

分布式一致性协议

🏛️Paxos算法

角色:Proposer(提议者,提出提案)、Acceptor(接受者,投票决定)、Learner(学习者,学习被选定的提案)
核心思想:通过多数派(Quorum)决议来保证一致性。任意两个多数派必有交集
两阶段:Prepare阶段(Proposer获取提议权)→ Accept阶段(Proposer提交提案并获多数接受)
问题:活锁问题(多个Proposer冲突),工程实现复杂

🌲Raft算法

Raft是Paxos的工程化实现,更易理解和实现。它将一致性问题分解为三个子问题:

三种角色Leader(领导者,处理客户端请求)、Follower(追随者,被动响应)、Candidate(候选人,参与选举)
Leader选举:Follower超时未收到Leader心跳后转为Candidate,发起选举请求,获得多数票后成为Leader
日志复制:Leader接收客户端请求后,将日志复制给Follower,多数节点确认后提交
容错:Raft容忍(N-1)/2台节点故障。5节点容忍2台故障,3节点容忍1台故障

🔗其他一致性协议

ZAB协议:Zookeeper Atomic Broadcast协议。基于Raft思想设计,包括崩溃恢复和消息广播两种模式。用于保证Zookeeper分布式一致性
Gossip协议:流言协议。节点随机选择其他节点交换信息,最终达到一致。优点:扩展性好、去中心化;缺点:最终一致性、消息延迟。适用:大规模集群、Dynamo/Cassandra
🎯
常考点:Raft容忍(N-1)/2台故障,即N节点集群最多允许(N-1)/2台节点宕机仍能正常工作。3节点容忍1台,5节点容忍2台。
Raft 节点状态转换图
Follower
追随者
超时未收到
Leader心跳
Candidate
候选人
获得
多数票
Leader
领导者
Leader 定期发送心跳 → Follower 保持追随|选举超时 → Candidate 发起投票
🔄

分布式事务-2PC/3PC

📋两阶段提交(2PC)

2PC是最经典的分布式事务协议,通过一个协调者(Coordinator)和多个参与者(Participant)完成。

阶段协调者行为参与者行为
第一阶段:准备阶段向所有参与者发送Prepare请求,询问是否可以提交执行事务操作但不提交,将Undo/Redo日志写入磁盘,返回Yes/No
第二阶段:提交阶段如果所有参与者都返回Yes,发送Commit请求;否则发送Rollback请求收到Commit则正式提交事务;收到Rollback则回滚事务
2PC 两阶段提交流程图
协调者
发送 Prepare 请求
参与者
执行事务,写 Undo/Redo 日志
参与者
返回 Yes / No
———— 第二阶段 ————
协调者
发送 Commit / Rollback
参与者
正式提交 / 回滚

⚠️2PC的缺点

同步阻塞:参与者在等待协调者响应期间处于阻塞状态,无法执行其他操作
单点故障:协调者宕机将导致参与者一直处于锁定状态
数据不一致风险:如果第二阶段网络异常,部分参与者收到Commit而部分未收到,导致数据不一致

📋三阶段提交(3PC)

阶段名称说明
第一阶段CanCommit协调者询问参与者是否可以执行事务(不执行实际操作)
第二阶段PreCommit参与者执行事务但不提交(类似2PC的Prepare)
第三阶段DoCommit协调者确认提交,参与者正式提交
💡
3PC的改进:相比2PC,3PC引入了超时机制和CanCommit阶段,降低了阻塞风险和单点故障影响。但3PC仍然存在网络分区时的数据不一致风险,实际使用较少。
🔧

分布式事务-补偿型方案

📌TCC(Try-Confirm-Cancel)

Try阶段:业务检查和资源预留。检查业务是否可执行,并预留所需资源。例如:冻结账户余额
Confirm阶段:确认执行业务。使用Try阶段预留的资源执行实际操作。例如:扣除已冻结的余额
Cancel阶段:取消执行,释放资源。当Try或Confirm失败时调用。例如:释放已冻结的余额

📋Saga模式

核心思想:将长事务拆分为多个本地短事务,每个短事务都有对应的补偿操作。如果某一步失败,则依次执行前面所有步骤的补偿操作
执行流程:T1 → T2 → T3 → ... → Tn,如果Ti失败,则执行Ci-1 → Ci-2 → ... → C1(补偿操作逆序执行)
协调方式:编排式(Orchestration,中心化协调器)和 协同式(Choreography,事件驱动)
适用场景:跨系统的长业务流程,如电商订单(创建订单→扣库存→支付→发货)
🎯
TCC vs 2PC:TCC是业务层的补偿机制,需要业务方实现Try/Confirm/Cancel三个接口;2PC是数据库层的协议,由数据库自动完成两阶段提交。TCC性能更好但开发成本更高。
📦

其他分布式事务方案

📝本地消息表

原理:在业务数据库中创建一张消息表,将业务操作和消息记录放在同一个本地事务中。定时任务扫描消息表发送消息
优点:实现简单、可靠,利用本地事务保证一致性
缺点:消息表与业务数据耦合、侵入业务逻辑

📨事务消息(RocketMQ)

半消息(Half Message):消息先发送到MQ但不投递给消费者,对消费者不可见
执行本地事务:生产者执行本地业务逻辑
消息回查:如果MQ未收到确认,定时回查生产者本地事务状态,根据结果决定Commit或Rollback消息
本质:本地消息表的MQ实现,利用两阶段提交思想

📡最大努力通知

原理:主动方按特定规则多次通知被动方,直到被动方确认收到为止
策略:递增间隔重试(1min→5min→30min→1h→...),超过最大次数后停止
适用:对一致性要求不高的场景,如支付结果通知

📊分布式事务方案对比

方案一致性保证性能复杂度适用场景
2PC强一致低(同步阻塞)跨数据库事务
3PC强一致改进版2PC
TCC最终一致高(业务侵入)对性能要求高的核心业务
Saga最终一致长业务流程
本地消息表最终一致简单消息可靠投递
事务消息最终一致RocketMQ生态
最大努力通知最终一致通知类业务

分布式缓存

💾Redis核心知识

数据结构:String(字符串/计数器)、List(列表/队列)、Set(集合/去重)、Hash(哈希/对象)、ZSet(有序集合/排行榜)
持久化:RDB(定时快照,恢复快但可能丢数据)、AOF(记录每条写操作,数据更安全但文件大)
集群模式:单机→主从复制→Sentinel(哨兵)高可用→Cluster分布式集群

🔴缓存三大问题对比

问题定义原因解决方案
缓存穿透查询缓存和数据库中都不存在的数据恶意攻击或数据不存在①布隆过滤器拦截 ②缓存空值(设置短过期时间)
缓存击穿单个热点Key过期瞬间,大量请求打到数据库热点Key集中过期①互斥锁(只允许一个线程重建缓存) ②热点Key永不过期
缓存雪崩大量Key同时过期或Redis宕机Key集中过期或Redis故障①设置随机过期时间 ②多级缓存 ③Redis集群高可用

🔄缓存一致性策略

策略读操作写操作特点
Cache Aside(旁路缓存)先读缓存,未命中则读DB并写入缓存先更新DB,再删除缓存最常用,可能出现短暂不一致
Read Through(读穿透)缓存负责加载数据缓存层封装数据加载逻辑
Write Through(写穿透)正常读缓存同时写缓存和DB(同步)数据一致性高,写性能较低
Write Behind(写回)正常读缓存只写缓存,异步写DB写性能最高,但有数据丢失风险
🎯
高频考点:Cache Aside策略中,更新数据时应该先更新DB再删除缓存(而非更新缓存),因为先更新缓存再更新DB可能导致并发时缓存中是旧数据。
📨

消息队列

📊消息队列三大产品对比

对比维度KafkaRabbitMQRocketMQ
开发语言Scala/JavaErlangJava
协议自定义TCP协议AMQP自定义协议
吞吐量极高(百万级/秒)中等(万级/秒)高(十万级/秒)
消息可靠性高(持久化+复制)高(持久化+确认机制)高(持久化+重试)
特色功能高吞吐、流处理灵活路由、延迟消息事务消息、顺序消息
适用场景日志收集、大数据、流处理业务消息、任务队列电商交易、金融系统

🎯消息队列核心应用场景

异步处理:将同步调用转为异步消息,提升响应速度。例如:用户注册后异步发送欢迎邮件
应用解耦:生产者和消费者通过消息队列解耦,互不影响。例如:订单系统与库存系统通过MQ解耦
流量削峰:将突发流量暂存于消息队列,消费者按处理能力消费。例如:秒杀活动
日志处理:集中收集和存储日志数据。例如:ELK通过Kafka收集日志
💡
选型建议:追求极致吞吐量选Kafka;需要灵活路由和消息可靠性选RabbitMQ;Java生态且需要事务消息选RocketMQ。
🧪

章节测验

🌐 第五章 · 分布式系统

第 1/15 题