分布式系统CAP定理探究
CAP定理探究-C还是A?
Ref
https://www.taooooooooooooooo.top/article/redis-ha
https://zh.wikipedia.org/wiki/CAP定理
https://github.com/maemual/raft-zh_cn/blob/master/raft-zh_cn.md
分布式系统中的CAP
来自维基百科:
在理论计算机科学中,CAP定理(CAP theorem),又被称作布鲁尔定理(Brewer's theorem),它指出对于一个分布式计算系统来说,不可能同时满足以下三点:
- 一致性(Consistency) (等同于所有节点访问同一份最新的数据副本)
- 可用性(Availability)(每次请求都能获取到非错的响应——但是不保证获取的数据为最新数据)
- 分区容错性(Partition tolerance)(以实际效果而言,分区相当于对通信的时限要求。系统如果不能在时限内达成数据一致性,就意味着发生了分区的情况,必须就当前操作在C和A之间做出选择。)
根据定理,分布式系统只能满足三项中的两项而不可能满足全部三项[4]。理解CAP理论的最简单方式是想象两个节点分处分区两侧。允许至少一个节点更新状态会导致数据不一致,即丧失了C性质。如果为了保证数据一致性,将分区一侧的节点设置为不可用,那么又丧失了A性质。除非两个节点可以互相通信,才能既保证C又保证A,这又会导致丧失P性质。
Raft
说到分布式一致性,那就绕不开Raft,Raft实现了强一致性,整个系统提案的提交都必须经过Leader才能应用,Leader利用AppendEntries指令不断联系每个Follower,力争保持整个集群的状态机层面的同步,Raft还利用领导人选举,心跳机制实现了分区容错
可以看出Raft协议实现的是Consistency和Partition tolerance,整个集群都力争向一致性靠拢,在Leader还没被选举出来,或者是存活的节点不过半的情况下,整个集群就会停摆,暂停向外界提供服务,直到自身恢复到正常
在强一致性第一的情况下,这个策略确实是必须的,Raft宁愿不提供服务也不愿意在强一致性状态没有实现的情况下提供服务
Redis集群+哨兵模式
Redis集群在生产环境非常常见,Redis的同步模式与Raft类似,都是主节点接受之后再传播给别的节点,实现一致性
需要注意的是,这里的一致性与Raft中的强一致性不同,Redis更多强调的是“弱一致性”,在很多环境下,Redis节点存储的一小部分kv是不是存在,版本是不是最新的其实并没有那么重要,比这更重要的是可用性
所以,Redis集群是典型的Availability+Partition tolerance,他容许在非强一致的情况下工作,Redis集群追求的更多是弱一致性或者“最终一致性”
弱一致性在生产环境下的应用回避了强一致性的可用性和性能问题
需要注意的是,Redis集群并没有采用raft的每个节点互相心跳的模式,而是引入了哨兵来实现节点健康的检测
个人的看法是:Redis早期没有保活机制,在原本的基础上加上心跳将导致复杂度过高,而引入哨兵这个第三者可以简化复杂度,而且可以在哨兵集群的基础上实现自动化运维
分区容错性
CAP看起来随机组合的可能性有三种,但是其实只有两种,因为分区容错性在分布式系统中几乎是必须的,在一个分布式系统中每个组件都有可能挂掉,必须要预料到这种情况