关于 designing-distributed-systems
供工程师和架构师规划分布式系统的设计技能,梳理一致性、复制、分区、弹性、事务、服务发现和缓存方面的权衡与模式。
主要功能
- 01CAP 与 PACELC 权衡指引
- 02一致性与复制模式
- 03分区策略选择
- 04弹性与事务模式
- 05服务发现和缓存指引
适用场景
- 01为多服务系统选择一致性模型
- 02规划跨区域复制方案
- 03设计服务故障恢复机制
- 04选择事务与缓存模式
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ ancoleman/ ai-design-components --skill designing-distributed-systems安装后在 Claude Code 中输入/designing-distributed-systems确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
outputs.yamldiagrams/caching-patterns.txtcap-theorem.txtreplication-topologies.txtsaga-flow.txtexamples/circuit-breaker/circuit_breaker.pyexamples/consistent-hashing/consistent_hash.pyexamples/cqrs/cqrs_example.pyexamples/event-sourcing/event_store.pyexamples/saga-orchestration/saga_orchestrator.pyexamples/service-discovery/consul_discovery.pyreferences/caching-strategies.mdcap-pacelc-theorem.mdconsensus-algorithms.mdconsistency-models.mdevent-sourcing-cqrs.mdpartitioning-strategies.mdreplication-patterns.mdresilience-patterns.mdsaga-pattern.mdservice-discovery.md详细介绍
设计分布式系统
使用经过验证的模式和一致性模型,设计可扩展、可靠且具备容错能力的分布式系统。
目的
分布式系统是现代云原生应用的基础。要构建能够全球扩展,同时保持正确性和可用性的系统,必须理解基本权衡(CAP 定理、PACELC)、一致性模型、复制模式和弹性策略。
何时使用此技能
适用于:
- 设计包含多个服务的微服务架构
- 构建必须跨多个数据中心或区域扩展的系统
- 在网络分区期间选择一致性或可用性
- 选择复制策略(单主、多主、无主)
- 实现分布式事务(Saga 模式、事件溯源、CQRS)
- 设计具备适当一致性保证的分区容错系统
- 使用熔断器、舱壁、重试机制构建弹性服务
- 实现服务发现和服务间通信
核心概念
CAP 定理基础
CAP 定理: 在发生网络分区的分布式系统中,必须在一致性(C)和可用性(A)之间做出选择。分区容错性(P)是必需的。
Network partitions WILL occur → Always design for P
During partition:
├─ CP (Consistency + Partition Tolerance)
│ Use when: Financial transactions, inventory, seat booking
│ Trade-off: System unavailable during partition
│ Examples: HBase, MongoDB (default), etcd
│
└─ AP (Availability + Partition Tolerance)
Use when: Social media, caching, analytics, shopping carts
Trade-off: Stale reads possible, conflicts need resolution
Examples: Cassandra, DynamoDB, Riak
PACELC: 将 CAP 扩展到正常运行(没有分区)的情况。
- 如果发生分区: 选择可用性(A)或一致性(C)
- 否则(正常情况): 选择延迟(L)或一致性(C)
一致性模型谱系
Strong Consistency ◄─────────────────────► Eventual Consistency
│ │ │
Linearizable Causal Consistency Convergent
(Slowest, (Middle Ground, (Fastest,
Most Consistent) Causally Ordered) Eventually Consistent)
强一致性(线性一致性):
- 所有操作看起来都按顺序原子执行
- 读取总是返回最新写入的数据
- 适用于:银行余额、库存、座位预订
- 权衡:延迟更高,可用性降低
最终一致性:
- 如果没有新的更新,所有副本最终都会收敛
- 适用于:社交动态、产品目录、用户资料、DNS
- 权衡:可能读取到旧数据,需要解决冲突
因果一致性:
- 所有节点都按相同顺序看到存在因果关系的操作
- 适用于:聊天应用、协同编辑、评论串
- 权衡:比最终一致性更复杂,需要跟踪因果关系
有界陈旧性:
- 陈旧程度受时间或版本数量限制
- 适用于:实时仪表板、排行榜、监控
- 权衡:必须监控滞后,比最终一致性更复杂
复制模式
1. 主从(单主):
- 所有写入都发送到主节点,再复制到从节点
- 从节点处理读取请求(分担负载)
- 同步: 等待从节点 ACK(强一致性,延迟更高)
- 异步: 不等待(最终一致性,可能丢失数据)
- 适用于:最常见的模式,通过同步复制实现强一致性
2. 多主:
- 多个主节点在不同数据中心接受写入
- 主节点之间相互复制
- 需要解决冲突: 最后写入获胜、应用合并、向量时钟
- 适用于:多数据中心、低写入延迟、地理分布式用户
- 权衡:冲突解决更复杂
3. 无主(Dynamo 风格):
- 没有单一主节点,读写基于法定人数
- 法定人数规则: W + R > N(W = 写入法定人数,R = 读取法定人数,N = 副本数)
- 示例:N = 5,W = 3,R = 2 → 强一致性(保证存在重叠)
- 适用于:最大限度提高可用性和分区容错性
- 权衡:复杂度较高,需要读修复
分区策略
哈希分区(一致性哈希):
- Key → Hash(Key) → 分区分配
- 分布均匀,添加或移除节点时只需进行最少的重新平衡
- 适用于:按 ID 进行点查询、均匀分布至关重要的场景
- 示例:Cassandra、DynamoDB、Redis Cluster
范围分区:
- 将 Key 范围分配给各个分区(A-F、G-M、N-S、T-Z)
- 支持范围查询和有序数据
- 风险:数据分布不均可能造成热点
- 适用于:时序数据、排行榜、范围扫描
- 示例:HBase、Bigtable
地理分区:
- 按位置进行分区(US-East、EU-West、APAC)
- 适用于:数据本地化、GDPR 合规、低延迟
- 示例:Spanner、Cosmos DB
弹性模式
熔断器:
[Closed] → Normal operation
│ (failures exceed threshold)
▼
[Open] → Fail fast (don't call failing service)
│ (timeout expires)
▼
[Half-Open] → Try single request
│ success → [Closed]
│ failure → [Open]
- 防止故障级联
- 快速失败,而不是等待超时
- 参见 references/resilience-patterns.md
舱壁隔离:
- 隔离资源(线程池、连接池)
- 一个分区中的故障不会影响其他分区
- 类似船舱隔间,可防止船只完全进水
超时与重试:
- 超时: 设置截止时间,超时后快速失败
- 重试: 使用带抖动的指数退避
- 幂等性: 确保重试安全(至关重要)
速率限制与背压:
- 保护服务免受过载影响
- 令牌桶、漏桶算法
- 背压:通知上游减缓速度
事务模式
Saga 模式:
- 协调跨服务的分布式事务
- 不使用分布式 2PC(两阶段提交)
编排: 服务对事件做出响应
Order Service → OrderCreated event
Payment Service → listens → PaymentProcessed event
Inventory Service → listens → InventoryReserved event
(Compensating: if payment fails → InventoryReleased event)
编排器: 中央协调器
Saga Orchestrator:
1. Call Order Service
2. Call Payment Service
3. Call Inventory Service
(If step fails → call compensating transactions in reverse)
事件溯源:
- 将状态变更存储为不可变事件
- 通过重放事件重建状态
- 审计追踪、时间回溯、调试
- 权衡:查询复杂度、快照优化
CQRS(命令查询职责分离):
- 分离读模型和写模型
- 写模型:规范化、事务性
- 读模型:反规范化、缓存、经过优化
- 适用于:读写模式不同、读写比例高(10:1+)的场景
- 常与事件溯源搭配使用
服务发现
客户端发现:
- 客户端查询服务注册表(Consul、etcd、Eureka)
- 客户端进行负载均衡并直接调用服务
- 优点:没有代理开销
- 缺点:客户端复杂度高
服务端发现:
- 客户端调用负载均衡器
- 负载均衡器查询注册表并路由请求
- 优点:客户端简单
- 缺点:负载均衡器可能成为单点故障
服务网格:
- Sidecar 代理处理服务发现、路由、重试和熔断
- 示例:Istio、Linkerd
- 优点:将通信逻辑与服务解耦
- 缺点:运维复杂度高
缓存策略
旁路缓存(延迟加载):
Read:
1. Check cache → hit? return
2. Miss? Query database
3. Store in cache, return
直写:
Write:
1. Write to cache
2. Cache writes to database synchronously
3. Return success
后写(回写):
Write:
1. Write to cache
2. Return success
3. Cache writes to database asynchronously (batched)
缓存失效:
- TTL(生存时间):经过指定时长后过期
- 基于事件:数据变更时使缓存失效
- 手动:更新时显式使缓存失效
决策框架
选择一致性模型
Decision Tree:
├─ Money involved? → Strong Consistency
├─ Double-booking unacceptable? → Strong Consistency
├─ Causality important (chat, edits)? → Causal Consistency
├─ Read-heavy, stale tolerable? → Eventual Consistency
└─ Default? → Eventual (then strengthen if needed)
选择复制模式
├─ Single region writes? → Leader-Follower
├─ Multi-region writes + conflicts OK? → Multi-Leader
├─ Multi-region writes + no conflicts? → Leader-Follower with failover
└─ Maximum availability? → Leaderless (quorum)
选择分区策略
├─ Need range scans? → Range Partitioning (risk: hot spots)
├─ Data residency requirements? → Geographic Partitioning
└─ Default? → Hash Partitioning (consistent hashing)
快速参考表
CAP/PACELC 系统对比
| 系统 | 分区时 | 否则(正常情况) | 使用场景 |
|---|---|---|---|
| Spanner | PC | EC(强一致性) | 全球 SQL |
| DynamoDB | PA | EL(最终一致性) | 高可用性 |
| Cassandra | PA | EL(可调) | 宽列存储 |
| MongoDB | PC | EC(默认) | 文档存储 |
| Cosmos DB | PA/PC | EL/EC(5 个级别) | 多模型 |
一致性模型用例
| 用例 | 一致性模型 |
|---|---|
| 银行账户余额 | 强一致性(线性一致) |
| 航空公司座位预订 | 强一致性(线性一致) |
| 库存数量 | 强一致性或有界一致性 |
| 购物车 | 最终一致性 |
| 产品目录 | 最终一致性 |
| 协同编辑 | 因果一致性 |
| 聊天消息 | 因果一致性 |
| 社交媒体点赞 | 最终一致性 |
| DNS 记录 | 最终一致性 |
仲裁配置
| 配置 | W | R | N | 一致性 | 用例 |
|---|---|---|---|---|---|
| 强一致 | 3 | 3 | 5 | 强一致性 | 银行业务 |
| 均衡 | 3 | 2 | 5 | 强一致性 | 默认配置 |
| 写入优先 | 2 | 3 | 5 | 强一致性 | 日志 |
| 读取优先 | 3 | 1 | 5 | 最终一致性 | 缓存 |
| 最大可用性 | 1 | 1 | 5 | 最终一致性 | 分析 |
渐进式披露
详细参考资料
如需深入了解特定主题,请参阅:
- references/cap-pacelc-theorem.md - CAP 和 PACELC 深入解析及 PACELC 矩阵
- references/consistency-models.md - 强一致性、最终一致性、因果一致性和有界陈旧性模式
- references/replication-patterns.md - 主从、多主和无主复制
- references/partitioning-strategies.md - 哈希、范围和地理分区示例
- references/consensus-algorithms.md - Raft 和 Paxos 概览(需要共识时)
- references/resilience-patterns.md - 熔断器、舱壁、超时、重试和限流
- references/saga-pattern.md - 编排与协同及可运行示例
- references/event-sourcing-cqrs.md - 事件溯源和 CQRS 实现模式
- references/service-discovery.md - 客户端、服务端和服务网格模式
- references/caching-strategies.md - Cache-aside、直写、回写和缓存失效
可运行示例
展示各种模式的完整可运行示例:
- examples/consistent-hashing/ - 带虚拟节点的一致性哈希实现
- examples/circuit-breaker/ - 带状态转换的熔断器模式
- examples/saga-orchestration/ - 带补偿事务的 Saga 编排器
- examples/event-sourcing/ - 支持重放和快照的事件存储
- examples/cqrs/ - 采用独立读写模型的 CQRS
- examples/service-discovery/ - 基于 Consul 的服务发现与注册
ASCII 图示
复杂概念的可视化表示:
- diagrams/cap-theorem.txt - CAP 定理决策树
- diagrams/replication-topologies.txt - 主从、多主和无主拓扑
- diagrams/saga-flow.txt - Saga 协同与编排流程
- diagrams/caching-patterns.txt - Cache-aside、直写和回写模式
与其他技能集成
相关技能:
Kubernetes 部署:参阅 kubernetes-operations 技能,了解 Pod 反亲和性和服务网格
基础设施:参阅 infrastructure-as-code 技能,了解分布式系统部署
数据库:参阅 databases-sql 和 databases-nosql,了解复制配置
消息传递:参阅 message-queues 技能,了解事件驱动架构和 Saga 编排
监控:参阅 observability 技能,了解分布式追踪和监控模式
测试:参阅 performance-engineering 技能,了解分布式系统负载测试
安全:参阅 security-hardening 技能,了解 mTLS 和服务身份验证
常见模式
多数据中心模式
1. Choose replication: Multi-leader or Leaderless
2. Partition data geographically
3. Implement conflict resolution (LWW, vector clocks, app-specific)
4. Monitor replication lag
5. Add circuit breakers between datacenters
事件驱动 Saga 模式
1. Define saga steps and compensating actions
2. Choose choreography (events) or orchestration (coordinator)
3. Implement idempotent handlers (retries safe)
4. Publish events with outbox pattern (transactional)
5. Monitor saga progress and timeouts
高可用模式
1. Use leaderless replication (N=5, W=3, R=2)
2. Partition with consistent hashing
3. Add circuit breakers for failing nodes
4. Implement read repair and anti-entropy
5. Monitor quorum health
最佳实践
针对故障进行设计:
- 网络分区会发生——始终针对分区容错进行设计
- 使用超时机制和指数退避重试
- 实现熔断器,防止故障级联
- 测试混沌工程场景(隔离节点、注入延迟)
谨慎选择一致性:
- 默认采用最终一致性,仅在必要时增强一致性
- 强一致性确实有代价(延迟、可用性)
- 使用有界陈旧度作为折中方案
幂等性至关重要:
- 将操作设计为可安全重试
- 使用唯一请求 ID 进行去重
- 对 saga 补偿事务至关重要
监控与观测:
- 使用关联 ID 进行分布式追踪
- 监控复制延迟和法定人数健康状况
- 在熔断器状态变化时发出告警
- 跟踪 saga 进度和故障
有策略地进行分区:
- 使用哈希分区实现均匀分布
- 使用范围分区支持范围查询(监控热点)
- 使用地理分区满足合规要求并降低延迟
为所有内容添加版本:
- 事件架构会演进——使用版本控制
- 使用 API 版本控制确保服务兼容性
- 在分布式系统中进行数据库架构迁移
应避免的反模式
分布式单体:
- 微服务之间紧密耦合
- 多个服务共用数据库
- 解决方法:每个服务使用独立数据库,采用异步通信
过度使用两阶段提交(2PC):
- 速度慢、会阻塞、降低可用性
- 解决方法:使用 saga 模式处理分布式事务
忽略网络故障:
- 假设网络可靠
- 解决方法:始终添加超时机制、重试和熔断器
处处采用强一致性:
- 带来不必要的延迟和复杂性
- 解决方法:默认采用最终一致性,仅在必要时增强一致性
没有冲突解决策略:
- 多主架构却不处理冲突
- 解决方法:选择 LWW、向量时钟或特定于应用的合并策略
缓存雪崩:
- TTL 过期,所有客户端都查询数据库
- 解决方法:使用概率性提前过期和请求合并
故障排查
复制延迟过高:
- 检查数据中心之间的网络带宽
- 监控主节点的写入吞吐量
- 考虑异步复制或多主架构
脑裂场景:
- 分区期间选出了多个主节点
- 解决方法:使用共识算法(Raft、Paxos)进行主节点选举
- 实现隔离令牌,防止双重写入
热点分区:
- 范围分区中的数据分布不均
- 解决方法:添加哈希组件、手动重新分配或使用复合键
Saga 超时/停滞:
- 服务不可用,saga 无法完成
- 解决方法:实现 saga 超时并自动回滚
- 使用死信队列进行人工干预
冲突解决失败:
- 多主冲突未得到处理
- 解决方法:实现明确的解决策略(LWW、合并、人工处理)
- 监控冲突率,并在冲突激增时发出告警