分布式系统概览
2026/10/11大约 4 分钟
分布式系统概览
分布式把一台机器扛不动的问题拆到多机,但代价是凭空多出三件事:部分失败、时钟不可靠、网络不可靠。理解这三件事,才谈得上正确地使用分布式组件。
1. 为什么单机不够
单体应用遇到天花板时,第一反应往往是「加机器」。但只要应用里还存在下面这些东西,加机器就解决不了问题,反而更乱:
- 进程内的本地 Session 或本地缓存 —— 用户这次落在 A 机器、下次落在 B 机器就登录态丢失。
- 写在本地磁盘的文件与日志 —— 换一台机器就读不到。
- 单库的写压力 —— 应用可以无限加,数据库连接池和磁盘 IOPS 是有限的。
于是要做两件事:横向扩展(把同一份逻辑部署多份)和拆分(按业务/数据把系统切成多个可独立部署的单元)。这两件事一旦做了,系统就进入「分布式」状态。
2. 分布式带来的新约束
分布式不是免费的午餐,它把原本由单机硬件保证的事情,变成了需要软件自己处理的难题:
| 约束 | 单机世界 | 分布式世界 | 应对手段 |
|---|---|---|---|
| 部分失败 | 要么整体活着,要么整体挂 | 某个节点挂了、某个请求超时了,其余照常 | 超时、重试、幂等、熔断 |
| 时钟不可靠 | 只有一个时钟 | 各机器时钟有偏差,还会回拨 | 逻辑时钟、单调时钟、不依赖物理时钟 |
| 网络不可靠 | 内存调用不会丢 | 消息会延迟、丢失、重复、乱序 | 幂等、去重、顺序保证、分区容忍 |
| 全局一致 | 单库事务天然保证 | 跨节点无法轻易原子提交 | 分布式事务 / 最终一致 |
核心心态
在分布式里,「不知道对方到底成没成」是常态。一次 RPC 超时,既可能是没执行,也可能是执行了但响应丢了。所有设计都必须容忍这种「不确定」——这正是幂等、对账、补偿存在的理由。
3. 三个绕不开的理论点
- CAP:网络分区(Partition)必然发生,于是系统在「一致」与「可用」之间取舍。详见 CAP 与 BASE。
- BASE:大规模互联网系统给出的工程答案——基本可用、软状态、最终一致,用来替代难以落地的强一致。
- FLP / 共识:在允许节点失效的异步网络中,不存在既能保证安全又能保证一定终止的确定性共识算法;工程上用 Paxos、Raft 这类协议在「大多数节点存活」的前提下达成一致。
4. 分布式基础设施清单
把理论落成工程,离不开一组基础组件:
| 能力 | 要解决的问题 | 本站专题 |
|---|---|---|
| 全局唯一标识 | 多库多表主键不再自增 | 分布式 ID 生成 |
| 跨节点互斥 | 定时任务防重、临界资源保护 | 分布式锁 |
| 跨库原子性 | 一个业务动作要写多个库 | 分布式事务 |
| 登录态共享 | 用户请求落到任意节点 | 分布式会话 |
| 协调与选主 | 配置同步、主从选举 | 分布式锁 / 治理相关章节 |
5. 设计原则
- 明确一致性需求:不是所有数据都要强一致。订单金额要强一致,商品浏览量用最终一致就够。先分级,再选组件。
- 超时、重试、幂等是标配:任何跨进程调用都要设超时;重试必须配合退避与预算控制;被调方必须幂等,否则重试就是灾难。
- 可观测性先于优化:上生产前先打通日志、指标、链路(见 可观测性),否则出问题只能靠猜。
- 优先消除分布式,而非解决分布式:能合并成一个本地事务的,就别拆成两个库再靠事务消息兜底。多数「分布式事务」的根源是拆分过度。
- 为失败设计:把「某个依赖挂了」当作正常运行的一部分,问自己:它挂了,我的系统怎么优雅降级?
6. 小结
- 分布式换来横向扩展与解耦,代价是部分失败、时钟与网络不可靠。
- CAP/BASE 是取舍的底层依据,一致性可以分级,不必一刀切。
- 分布式 ID、锁、事务、会话是四类高频基础设施,各自有专门的选型权衡。
- 一致的态度是:能不分布式就不分布式;分布式了,就为失败而设计。