分布式系统
分布式系统解决单机算力不足、高可用、数据一致性等核心问题。分布式带来的挑战包括网络延迟、节点故障、数据一致性,这些挑战催生了 CAP 定理、BASE 理论、各种共识算法和事务方案。
提示
分布式事务、共识算法等分布式系统核心问题与解决方案
分布式系统的挑战
把系统从单机搬到多机,本质是用硬件冗余换可靠性,但引入了单机不存在的问题:
| 挑战 | 单机 | 分布式 | 后果 |
|---|---|---|---|
| 网络 | 进程内调用,无延迟 | 远程调用,有延迟和丢包 | 超时、重试、幂等 |
| 故障 | 崩溃即全挂,无歧义 | 部分故障(幽灵节点) | 无法区分「慢」还是「死」 |
| 一致性 | 内存/单库天然一致 | 多副本可能不一致 | CAP 权衡 |
| 时钟 | 本地时钟可信 | 各节点时钟漂移 | 事件排序困难 |
核心心智模型:在分布式系统中,任何假设都可能被打破(消息会丢失、节点会假死、时钟会漂移),架构设计的目标是让系统在这些「异常」下依然正确或可接受地降级。
一致性与可用性权衡
分布式事务 从 CAP 定理出发:分布式系统最多只能同时满足一致性、可用性、分区容忍性中的两个。实际工程中分区容忍性是必须选择的,因此需要在 CP 和 AP 之间权衡。金融交易系统选择 CP(强一致性优先),社交网络、秒杀系统选择 AP(高可用优先)。
BASE 理论是对 CAP 中一致性和可用性权衡的结论:基本可用、软状态、最终一致性。与 ACID 的强一致性相比,BASE 提供柔性的最终一致性,适用于高并发场景。
分布式事务方案
分布式事务 文件详细介绍了 2PC、TCC、SAGA、AT 模式。2PC 是同步阻塞的两阶段提交,存在单点故障和数据不一致风险。TCC 是业务层面的两阶段提交,Try 阶段预留资源,Confirm 确认执行,Cancel 取消释放。SAGA 一阶段直接提交本地事务,失败时通过补偿操作回滚。AT 模式(Seata)自动生成回滚 SQL,无侵入但有全局锁。
选型建议:单服务多数据源用 XA 模式,普通业务微服务用 AT 模式,高并发核心系统用 TCC,长事务用 SAGA,异步场景用可靠消息队列。
共识算法
分布式共识算法 解决多个节点如何就同一个值达成一致的问题。FLP 不可能定理指出,在异步网络中只要有一个节点可能崩溃,就不存在算法能一定达成共识。实践中的解决方案:放弃一定,改为概率保证(Paxos/Raft)或最终一致(Gossip)。
Paxos 是 Leslie Lamport 提出的分布式共识算法,是后续多种算法的基础。Raft 的设计目标是比 Paxos 更易于理解,将共识问题拆分为 Leader 选举、日志复制、安全性三个独立模块。Gossip 模拟流行病传播,每个节点随机与其他节点交换信息,最终所有节点获得相同数据。
注册中心与共识
服务治理 中的注册中心是共识算法的典型应用。Nacos 的 CP 模式使用 Raft 保证强一致性,AP 模式使用 Distro(基于 Gossip)保证最终一致性。ZooKeeper 使用 ZAB 协议(基于 Paxos),Eureka 遵循 AP 原则,当心跳失败比例超过 85% 时进入保护模式。
选型建议:分布式配置/元数据用 Raft(etcd),集群成员关系用 Gossip,注册中心 AP 用 Gossip/Distro。
分布式系统其他主题
- 分布式锁:Redis SetNX(AP,快)/ ZooKeeper 临时节点(CP,可靠),Redis 分布式锁存在主从切换丢锁问题,严格场景用 Redlock 或 etcd
- 分布式 ID:雪花算法(Snowflake,时间+机器+序列)、号段模式(DB 批量取号)、UUID(无序,不适合做索引)
- 分布式幂等:见 远程服务调用,唯一约束、SetNX、乐观锁、状态机
- 分布式调度:xxl-job、ElasticJob,解决定时任务在多实例下不重复执行的问题
FAQ
Q: 为什么分区容忍性(P)是必须选择的? A: 网络分区(节点间通信中断)在分布式系统中不可避免——交换机故障、机房断网都可能发生。一旦分区发生,系统必须在「保持一致性而拒绝服务(CP)」和「保持可用性但可能不一致(AP)」之间二选一。CA 组合只存在于不存在分区的理想单机世界。
Q: 分布式系统一定比单体强吗? A: 不一定。分布式是用复杂度换规模和高可用,只有单机确实撑不住(容量、可用性 SLA、地理分布)时才划算。能用单机解决的问题,分布式是过度设计;数据规模上来后,分库分表往往比上分布式事务框架更先出现。