第4章 分布式系统基础:CAP、一致性协议、分布式事务、幂等性设计

在微服务架构中,分布式系统的核心挑战在于数据一致性、可用性与分区容忍性的平衡。面试中,面试官通常从CAP理论出发,逐步深入一致性协议(如Raft)、分布式事务(如Seata AT)以及幂等性设计。本章提供结构化问答框架与真实项目模板,帮助你在面试中展现系统思考能力。

CAP 理解 三选二权衡 一致性协议选型 Raft / Paxos 分布式事务实现 Seata AT / TCC 幂等性设计 唯一键 / 状态机 项目实践验证 你的具体方案 面试官追问路径:从理论到实践层层递进

核心概念速览

概念 核心要点 常见方案
CAP 一致性、可用性、分区容忍性三者最多满足两个 CP 系统(ZooKeeper)、AP 系统(Eureka)
一致性协议 通过多数派投票保证强一致 Raft(Leader+日志复制)、Paxos
分布式事务 跨服务事务一致性解决方案 Seata AT、TCC、Saga
幂等性 同一操作多次执行结果一致 唯一键、乐观锁、状态机

面试问题

请解释CAP理论,并说明在微服务架构中如何权衡。

面试官考察点

  • 是否真正理解三选二的本质,而非死记硬背。
  • 能否结合实际业务场景给出取舍理由。

回答框架

  1. 定义C、A、P三个属性。
  2. 说明分区容忍性是必选项,实际在C和A间权衡。
  3. 举例:配置中心选CP(强一致),服务注册选AP(高可用)。

简短示例回答

CAP定理指一致性、可用性、分区容忍性三者不可兼得。分布式系统中P必选,因此在C和A间取舍。例如ZooKeeper保证CP,适合配置中心;Eureka保证AP,适合注册中心。具体选择需结合业务对一致性的容忍度。

可能追问

你如何理解最终一致性?在项目中有哪些实践?

避坑提醒

不要直接回答“选择CP或AP”,必须说明业务场景和取舍理由,否则显得缺乏实践。

面试问题

请简述Raft一致性协议的核心机制,并说明其如何保证强一致性。

面试官考察点

  • 对分布式共识算法的理解深度。
  • 能否清晰描述角色、选举和日志复制流程。

回答框架

  1. 介绍三种角色:Leader、Follower、Candidate。
  2. Leader选举:节点超时后发起选举,获得多数票成为Leader。
  3. 日志复制:Leader接收请求,写入日志后广播给Follower,多数确认后提交。

简短示例回答

Raft通过Leader统一处理写操作保证强一致。选举时随机超时机制避免冲突,获得多数票即成为新Leader。日志复制采用两阶段提交:Leader将日志项追加到本地并广播,多数Follower写入成功后标记为已提交。整个流程通过任期和心跳维持。

可能追问

Raft如何保证日志的一致性?如何处理网络分区?

避坑提醒

不要混淆Raft和Paxos,强调Raft的易理解性和更强的Leader角色;同时要提到常用的实现(如Go的etcd)。

面试问题

在微服务中如何实现分布式事务?以Seata AT模式为例说明其原理。

面试官考察点

  • 是否掌握主流分布式事务方案及其适用场景。
  • 对AT模式底层实现的理解(拦截SQL、生成回滚镜像)。

回答框架

  1. 先简述两阶段提交(2PC)思想。
  2. 说明Seata AT自动生成undo日志,对业务代码侵入小。
  3. 一阶段执行SQL并记录前后镜像,二阶段根据结果提交或回滚。

简短示例回答

Seata AT模式基于2PC,通过AOP拦截SQL,自动生成before/after镜像并写入undo_log。一阶段执行业务SQL并提交本地事务,二阶段如果全局成功则异步删除undo_log,失败则用镜像回滚。优点是业务代码零侵入,适合一致性要求高的场景,但性能受限于两阶段交互。

可能追问

AT模式和TCC模式有什么区别?你们项目如何选型?幂等性如何保证?

避坑提醒

不要只说理论,必须结合真实项目经验;指出AT模式不适合长事务和网络频繁抖动场景,并说明幂等性方案(如唯一主键、状态机)。

项目案例:金融支付系统中的分布式事务与幂等性设计

项目名称 亿级流量支付结算系统
业务背景 网关收单、账户扣款、订单状态同步等多个服务需保证最终一致性,同时要处理重复回调、超时重试等场景。
规模指标 日均交易量 300 万笔,峰值 TPS 5000,参与服务节点 12 个。
技术栈 Go + gRPC + Kafka + Redis + MySQL + Seata(AT模式)
核心难点
  • 跨服务事务一致性(扣款成功但订单未更新)
  • 幂等性防重放(支付回调、MQ消费重复)
  • Seata AT 模式下 undo_log 膨胀导致的性能问题
面试高频追问
  • 为什么选择 Seata AT 而不是 TCC?
  • 幂等性具体怎么实现?用 Redis 还是数据库唯一键?
  • 如何应对 Seata 全局锁竞争导致超时?
  • undo_log 清理策略是什么?
可迁移回答话术 “我们采用 Seata AT 模式配合全局唯一流水号实现幂等。一阶段事务中通过 SELECT ... FOR UPDATE 锁住关键行,二阶段依赖 undo_log 回滚。对于重复回调,在 Redis 中设置 key(txId+场景),执行前检查是否已消费。此方案对业务侵入小,适合我们高频、短事务的场景。对于长事务会考虑 TCC 或 Saga。”
讲师提示: 面试中分布式系统问题往往连环追问,建议准备一个自己熟悉的项目(如上案例),用 STAR 法则阐述选型、实现、效果和坑。