16.CAP
# 01.AP 定理详解
- CAP定理,指出在分布式系统中,不可能同时完美满足这三大特性
- 一致性(Consistency)
- 可用性(Availability)
- 分区容忍性(Partition Tolerance)
- CAP定理给出了分布式系统的三大核心难题
- 由于分布式系统中网络分区不可避免,设计者必须在
一致性和可用性
之间做出权衡 通过理解CAP定理
,开发者可以针对具体应用场景选择合适的系统架构和数据库模型
- 由于分布式系统中网络分区不可避免,设计者必须在
# 1、CAP 三要素详解
# 1)一致性(Consistency)
- 定义:
- 所有节点在
同一时间拥有相同的数据
- 即每次读操作无论在哪个节点进行,都会返回最新写入的数据
- 所有节点在
- 表现:
- 分布式系统中的
每次写操作都保证同步到所有节点
- 之后所有的
读操作
都能立即获得最新的数据
- 分布式系统中的
- 难点:
- 在实际网络环境中,可能会有延迟、网络丢包或者分区情况
- 导致节点无法及时同步数据,影响一致性
# 2)可用性(Availability)
- 定义:
- 系统中的每个节点在
响应时间内必须返回结果
,无论结果是成功还是失败
- 系统中的每个节点在
- 表现:
- 系统即使在
出现故障或网络分区时
,仍能处理请求,并返回一定的结果
- 系统即使在
- 难点:
- 在节点失效或网络分区的情况下,保证每个请求都能响应
- 可能需要
放宽对数据一致性的要求
# 3)分区容忍性(Partition Tolerance)
- 定义:
- 系统能够容忍网络分区的发生,即使
部分节点之间的通信中断
,整个系统仍能继续提供服务
- 系统能够容忍网络分区的发生,即使
- 表现:
- 当集群中存在某些节点无法相互通信时,系统能继续运行,不至于完全失效
- 难点:
- 分区容忍性通常需要
依赖冗余、数据副本等机制
- 但这些机制可能
与一致性和可用性冲突
- 分区容忍性通常需要
# 2、CAP 三者不可兼得
- CAP定理的核心思想是,在网络分区发生时,分布式系统必须在一致性和可用性之间进行权衡
- 如果网络保持正常,不出现分区,系统可以同时满足一致性和可用性
- 但网络分区在分布式系统中是不可避免的,因此,在实际应用中无法同时保证三者
① CP类系统:一致性 + 分区容忍性
为了确保一致性和分区容忍性,系统在出现网络分区时会选择牺牲部分可用性
例如,
系统会暂停某些服务,直到恢复网络,保证一致性
示例:
Zookeeper、Raft
协议等系统在网络故障时,会暂停写操作来保证数据的一致性- 它们牺牲了一部分可用性,但保证了强一致性
② AP类系统:可用性 + 分区容忍性
保证在网络分区情况下系统依然可用,但可能会牺牲数据的一致性
通常通过异步复制和最终一致性模型来解决数据一致性问题
示例:
- Cassandra、DynamoDB等分布式NoSQL数据库
- 允许在分区情况下处理请求,并在网络恢复后通过数据同步达到最终一致性
# 3、CAP 定理的权衡
- 强一致性 vs 最终一致性
- 强一致性(如CP系统)意味着每次数据变更在所有节点之间必须同步才能继续操作
- 而最终一致性(如AP系统)允许在一段时间内节点间数据不一致,但最终达到一致
- 一致性和可用性的平衡
- 在互联网系统中,尤其是高可用服务中,很多系统会优先选择AP模式
- 因为
保证可用性比 强一致性 更加重要
,例如社交媒体中的“点赞”操作,允许短暂的不一致
- 分布式数据库的实践
- 如Cassandra、DynamoDB采用最终一致性模型,适用于全球分布的系统,
数据量大且要求高可用的场景
- 而像
etcd、Zookeeper
这样的系统,应用于要求强一致性如分布式锁、选举等场景
,保证CP的特性
- 如Cassandra、DynamoDB采用最终一致性模型,适用于全球分布的系统,
# 4、常见数据库选择
系统/数据库 | CAP 特性 | 选择原因 |
---|---|---|
MySQL | CP | 保证数据一致性,牺牲分区容忍性,主要应用于单点集群场景 |
RabbitMQ | CP | 保证消息一致性和可用性,适用于高可靠性场景 |
Kafka | CP | 保证消息一致性和分区容忍性,适合数据流处理和日志系统 |
etcd | CP | Raft协议保证一致性和分区容忍性,适用于分布式锁和服务发现 |
Consul | CP | Raft协议保证一致性和分区容忍性,服务发现与配置管理 |
Redis | AP | 高可用性和分区容忍性优先,适合缓存场景 |
Elasticsearch | AP | 保证高可用性和分区容忍性,异步数据复制实现最终一致性 |
Nacos | AP | 高可用性和分区容忍性,适合微服务场景 |
# 1)CP
① MySQL
(CA 一致性 + 可用性)② RabbitMQ
(CA 一致性 + 可用性)③ Kafka
(CP 一致性 + 分区容忍性)Kafka是一个分布式消息队列系统,主要关注一致性和分区容忍性
为了保证消息的顺序和准确性,Kafka通过
同步复制机制保证数据一致性
,在某些情况下会牺牲可用性(例如等待数据同步)Kafka的分区容忍性较好,
能够容忍节点宕机或网络分区问题
,但在这些情况下可用性可能受到影响应用场景:
- 适用于
日志收集
、实时数据流处理
等需要严格保证消息顺序和一致性的场景
- 适用于
④ etcd
(CP 一致性 + 分区容忍性)etcd是一个基于
Raft算法
的分布式键值存储系统,主要保证一致性和分区容忍性在出现分区或节点故障时,etcd通过多数派选举机制选出新的Leader,并暂停部分服务直到一致性得到保证
为了保持数据的一致性,etcd在某些情况下牺牲了可用性
应用场景:
- 适用于需要强一致性的场景,如分布式锁、服务发现和配置管理(Kubernetes使用etcd作为其核心数据存储)
⑤ Consul
(CP 一致性 + 分区容忍性)Consul同样是基于
Raft协议
的分布式系统,优先考虑一致性和分区容忍性它在集群选举过程中保证强一致性,避免不一致的数据在服务发现和配置管理中的出现
分区情况下,
部分服务可能暂停,但系统保证数据的一致性
应用场景:
- 服务发现、配置管理、健康检查等需要一致性较高的场景
# 2)AP
⑥ Redis
(AP 可用性 + 分区容忍性)Redis默认使用主从复制模式,主要是为了高可用性
在分区情况下,Redis优先保证可用性,并允许节点间的数据暂时不同步
因此,Redis提供的是最终一致性而不是强一致性
同时,Redis在使用哨兵(Sentinel)模式或Redis Cluster模式下,也偏向于可用性和分区容忍性
应用场景:
- 主要用于缓存和高吞吐量的场景,如会话管理、计数器等
⑦ Elasticsearch (ES)
(AP可用性 + 分区容忍性)Elasticsearch是一个分布式搜索引擎,在设计上优先考虑可用性和分区容忍性
当
网络分区或节点故障时
,ES依然可以继续接收查询和写入请求
,节点故障时通过分片自动恢复数据数据的一致性是通过异步复制来保证的,因此数据在短时间内可能不一致,但最终达到一致性
应用场景:
- 适合需要高查询性能和横向扩展的场景,如日志分析、全文搜索
⑧ Nacos
(AP可用性 + 分区容忍性)Nacos在设计时更偏向于可用性和分区容忍性,主要用于微服务架构中的服务发现和配置管理
在分区的情况下,Nacos依然能提供服务注册和发现的功能
尽管数据一致性可能会暂时无法保证,最终一致性会在分区恢复后达到
应用场景:
- 适合需要高可用性和分布式部署的微服务架构,特别是云原生应用场景中