分篇三:分布式系统设计

一、CAP 定理

1. 定义

在一个分布式系统中,以下三个特性最多只能同时满足两个

特性 含义
C(Consistency,一致性) 所有节点在同一时刻看到的数据一致
A(Availability,可用性) 每个请求都能在合理时间内收到非错误响应
P(Partition tolerance,分区容错性) 系统在网络分区发生时仍能继续运行

2. 为什么必须选 P

在真实分布式环境下,网络分区不可避免,因此 P 必须保留。实际选择只剩:

  • CP 系统:保证一致性,牺牲部分可用性。例:ZooKeeper、HBase
  • AP 系统:保证可用性,允许短暂不一致。例:Cassandra、DNS、DynamoDB

3. 案例题考法

通常不会直接问 CAP 定义,而是给出分布式场景让你分析:

  • 为什么该系统允许最终一致
  • 为什么该系统必须强一致
  • 某方案属于 CP 还是 AP

二、BASE 理论

1. 定义

BASE 是 CAP 中 AP 思路的落地指导,全称:

缩写 含义 说明
BA(Basically Available) 基本可用 允许部分功能降级或延迟,但核心可用
S(Soft State) 软状态 允许系统存在中间状态(如数据同步中)
E(Eventually Consistent) 最终一致 一段时间后所有副本数据趋于一致

2. BASE vs ACID

维度 ACID BASE
一致性模型 强一致 最终一致
关注点 正确性 可用性与吞吐
适用场景 传统关系型数据库事务 分布式系统
代表 MySQL 事务 NoSQL、消息队列

三、分布式事务

1. 为什么需要分布式事务

当业务操作跨越多个服务或多个数据库时,单机事务无法保证全局一致性。例如:下单扣库存 + 扣余额 + 创建订单,涉及三个服务。

2. 常见方案

2.1 两阶段提交(2PC)

原理: 由一个协调者 统一管理多个参与者的事务提交。

阶段一:准备阶段(Prepare/Vote)

  1. 协调者向所有参与者发送"准备提交"请求
  2. 各参与者执行事务操作(但不提交),写 undo/redo 日志
  3. 各参与者回复"同意"或"中止"

阶段二:提交阶段(Commit/Abort)

  • 如果所有参与者都同意:协调者发送"提交",所有参与者正式提交
  • 如果有任何一个参与者中止:协调者发送"回滚",所有参与者回滚

优点: 保证强一致性

缺点:

  • 同步阻塞:参与者在等待协调者指令期间处于阻塞状态
  • 单点故障:协调者故障可能导致参与者永久阻塞
  • 数据不一致风险:网络异常时部分参与者可能提交、部分回滚
2.2 三阶段提交(3PC)

在 2PC 基础上增加了一个预提交(PreCommit)阶段,并引入了超时机制

  1. CanCommit:协调者询问是否可以执行
  2. PreCommit:参与者预执行并锁定资源
  3. DoCommit:正式提交

改进点: 减少阻塞、引入超时自动决策。
不足: 实现复杂,仍无法完全避免不一致。

2.3 TCC(Try-Confirm-Cancel)

原理: 将每个分布式操作拆分为三个阶段:

阶段 含义 说明
Try 尝试 预留资源(如冻结库存、冻结金额)
Confirm 确认 正式提交(扣除冻结的资源)
Cancel 取消 回滚(释放冻结的资源)

优点:

  • 无需数据库级锁,业务层面控制
  • 并发性能好

缺点:

  • 每个业务都要写 Try/Confirm/Cancel 三套逻辑,开发成本高
  • 需要保证 Confirm 和 Cancel 的幂等性

适用场景: 高并发、对性能要求高的场景(如支付、转账)

2.4 Saga

原理: 将一个长事务拆分为多个本地事务 ,每个本地事务有对应的补偿事务。正向执行时依次调用各本地事务;若某步失败,则逆序执行已完成步骤的补偿事务。

两种实现方式:

  • 编排式(Choreography):各服务通过事件驱动自行协调
  • 协调式(Orchestration):由一个中心协调器统一调度

优点:

  • 不需要分布式锁
  • 各步骤独立事务,性能好

缺点:

  • 只保证最终一致性
  • 补偿逻辑可能复杂
  • 编排式难以追踪全局状态

3. 分布式事务方案对比

方案 一致性 性能 实现复杂度 适用场景
2PC 强一致 差(阻塞) 传统数据库
3PC 强一致 一般 理论居多
TCC 最终一致 高(三套逻辑) 高并发业务
Saga 最终一致 长流程业务

四、分布式锁

1. 为什么需要分布式锁

当多个服务实例同时操作同一资源(如更新订单状态)时,需要互斥机制来保证同一时刻只有一个实例能执行关键操作。

2. 三种主流实现

2.1 基于数据库的分布式锁

实现方式: 在数据库中创建一张锁表,通过插入记录 抢锁,操作完成后删除记录 释放锁。也可用 SELECT ... FOR UPDATE 行锁实现。

优点:

  • 实现简单,无需额外中间件
  • 数据持久化,便于审计

缺点:

  • 数据库成为单点,性能瓶颈
  • 若进程异常退出,锁记录可能永久存在(锁泄漏
  • 高并发下锁争用严重
  • 无原生过期机制
2.2 基于 Redis 的分布式锁

实现方式: 使用 SET key value NX EX timeout 命令:

  • NX:仅当 key 不存在时设置成功(互斥)
  • EX:设置过期时间(防死锁)
  • value:设为随机唯一值(释放时验证身份,防误删)

释放锁: 用 Lua 脚本保证"检查 value + 删除 key"的原子性。

优点:

  • 性能高、延迟低
  • 支持自动过期

缺点:

  • 主从切换时可能丢锁(Master 挂掉,锁未同步到 Slave)
  • 需要处理续租问题(业务执行时间超过过期时间)
  • 实现需要注意原子性与幂等性

Redlock 算法(了解): 为解决单节点 Redis 锁的可靠性问题,Redis 作者提出 Redlock:向 N 个独立 Redis 节点请求锁,获取 N/2+1 个以上才算成功。

2.3 基于 ZooKeeper 的分布式锁

实现方式: 利用 ZooKeeper 的临时顺序节点

  1. 每个客户端在指定路径下创建临时顺序节点
  2. 检查自己是否是序号最小的节点
  3. 如果是,获得锁;否则监听前一个节点的删除事件
  4. 前一个节点删除后,再检查自己是否最小

优点:

  • 客户端断开连接,临时节点自动删除(天然防死锁
  • 顺序节点实现公平锁
  • ZooKeeper 集群本身高可用

缺点:

  • 性能不如 Redis(涉及 ZK 集群同步)
  • 需要维护 ZooKeeper 集群
  • 实现相对复杂
2.4 基于 Etcd 的分布式锁

实现方式: 利用 Etcd 的租约(Lease)+ 前缀 + 事务机制。

优点: 租约天然解决过期问题、强一致性(Raft 协议)。

缺点: 相对小众,生态不如 ZK/Redis。

3. 分布式锁对比总结

维度 数据库 Redis ZooKeeper Etcd
性能
可靠性 中(单点) 中(主从问题)
实现复杂度
防死锁 需自行处理 过期机制 临时节点 租约机制
公平性 有(顺序节点)

五、负载均衡

1. 定义

将请求分发到多个服务器实例,以提升系统吞吐量和可用性。

2. 常见算法

算法 原理 特点
轮询(Round Robin) 依次分配给每台服务器 简单、公平,不考虑服务器差异
加权轮询 按权重分配,高性能机器分更多 适应异构环境
随机 随机选一台 简单,大量请求下趋于均匀
最少连接 分配给当前连接数最少的服务器 适合长连接场景
IP 哈希 对客户端 IP 取哈希决定分配 保证同一客户端落到同一服务器
一致性哈希 哈希环 + 虚拟节点 节点增减时只影响相邻数据

3. 一致性哈希

原理:

  1. 将哈希值空间组织成一个虚拟的(0 ~ 2^32-1)
  2. 将服务器节点映射到环上
  3. 将数据的 Key 也映射到环上,沿顺时针找到第一个服务器节点就是目标

虚拟节点: 为避免数据倾斜,将每个物理节点映射为多个虚拟节点均匀分布在环上。

优点: 增减节点时,只影响环上相邻区间的数据迁移,影响范围小。

适用场景: 分布式缓存、分布式存储的数据分片。


六、服务治理

1. 服务注册与发现

组件 说明
服务注册中心 维护所有服务实例的地址信息(如 Nacos、Consul、Eureka、ZooKeeper)
服务注册 服务启动时向注册中心登记自己的地址与元信息
服务发现 调用方从注册中心获取目标服务的地址列表
健康检查 注册中心定期探测服务实例是否存活

2. 限流

目的: 保护系统不被突发流量击垮。

算法 原理
固定窗口计数器 在固定时间窗口内计数,超过阈值则拒绝
滑动窗口计数器 窗口随时间滑动,统计更平滑
漏桶(Leaky Bucket) 请求进入桶中,以固定速率流出
令牌桶(Token Bucket) 以固定速率生成令牌,请求消耗令牌

3. 熔断

目的: 当下游服务不可用时,快速失败,避免级联故障。

三种状态:

  • 关闭(Closed):正常调用,统计失败率
  • 打开(Open):达到阈值后直接返回错误,不再调用下游
  • 半开(Half-Open):一段时间后试探性放入少量请求,成功则关闭断路器

4. 降级

目的: 系统压力过大时,主动放弃部分非核心功能,保证核心功能可用。

常见方式:

  • 返回兜底数据(如缓存中的旧数据)
  • 关闭非核心功能
  • 简化业务流程

5. 限流、熔断、降级的区别

维度 限流 熔断 降级
保护对象 保护自身 保护自身(不被下游拖垮) 保护核心功能
触发条件 流量超阈值 下游失败率过高 系统资源不足
处理方式 拒绝超出请求 快速失败 关闭非核心功能

七、微服务拆分原则

案例题如果涉及微服务设计,可能会问拆分原则:

  1. 单一职责原则:每个服务只做一件事
  2. 业务边界清晰:围绕业务能力拆分,而非技术层
  3. 高内聚低耦合:服务内部紧密相关,服务之间尽量独立
  4. 数据自治:每个服务拥有自己的数据库
  5. 可独立部署:服务升级不应要求其他服务同时升级
  6. 适当粒度:不要拆太细(增加运维复杂度),也不要太粗(退化为单体)

八、答题模板

分布式锁优缺点题

基于 [X] 的分布式锁:

  • 优点:1. ... 2. ...
  • 缺点:1. ... 2. ...
  • 适用场景:...

分布式事务对比题

按以下维度逐项对比:一致性级别、性能、实现复杂度、适用场景。

微服务概念题

微服务是一种架构风格,将单体应用拆分为一组小型服务,每个服务运行在独立进程中,通过轻量级通信机制协作,可独立部署。

优点: 1. ... 2. ... 3. ... 4. ...

挑战: 1. ... 2. ... 3. ... 4. ...

相关推荐
钮钴禄·爱因斯晨3 小时前
聚焦操作系统中的PV操作
数据库·算法·系统架构·c#
小江的记录本8 小时前
【分布式】分布式一致性协议:2PC/3PC、Paxos、Raft、ZAB 核心原理、区别(2026必考Raft)
java·前端·分布式·后端·安全·面试·系统架构
小江的记录本10 小时前
【分布式】分布式核心组件——分布式ID生成:雪花算法、号段模式、美团Leaf、百度UidGenerator、时钟回拨解决方案
分布式·后端·算法·缓存·性能优化·架构·系统架构
开心就是最好21 小时前
软件架构风格全面总结
系统架构
小江的记录本1 天前
【系统设计】《2026高频经典系统设计题》(秒杀系统、短链接系统、订单系统、支付系统、IM系统、RAG系统设计)(完整版)
java·后端·python·安全·设计模式·架构·系统架构
池佳齐1 天前
软考高级系统架构设计师备考(十一):操作系统—嵌入式系统
系统架构
黄俊懿2 天前
【架构师从入门到进阶】第五章:DNS&CDN&网关优化思路——第一节:DNS优化
网络·计算机网络·架构·系统架构·cdn·dns·架构设计
沛沛rh452 天前
用 Rust 实现用户态调试器:mini-debugger项目原理剖析与工程复盘
开发语言·c++·后端·架构·rust·系统架构
一几文2 天前
软考高级系统架构师25年下半年案例分析真题回顾带解析1,质量属性+质量属性场景+AES-256加密算法
架构·系统架构·软考高级·软考·aes·考证·质量属性