分布式系统

脑裂(split-brain)

分布式集群系统一般都有一个中央控制节点,叫Master或Leader节点,它们往往是通过选举产生的。在网络正常的情况下,可以顺利的选举出Leader。但当两个机房之间的网络通信出现故障时,选举机制就有可能在不同的网络分区中选出两个Leader,形成两个互相分割的子集群。每个子集群都认为自己是完整的集群并对外提供服务,导致无法维持数据一致性,这就出现了“脑裂”现象。

解决脑裂的常见方案 - Quorums(大多数):比如3个节点的集群,Quorums = 2,也就是说集群可以容忍1个节点失效,这时候还能选举出1个lead,集群还可用。比如4个节点的集群,它的Quorums = 3,Quorums要超过3,相当于集群的容忍度还是1,如果2个节点失效,那么整个集群还是无效的。这是Zookeeper防止“脑裂”默认采用的方法。

CAP原则

CAP原则又称CAP定理,指的是在一个分布式系统中,一致性(Consistency)、可用性(Availability)、分区容忍性(Partition tolerance)这三个要素最多只能同时实现两点,不可能三者兼顾。

  • 分区容忍性(Partition tolerance):尽管网络或节点故障导致节点间通信中断一次或多次,但系统仍继续运行。
  • 一致性(Consistency):每个Client都看到相同的数据。每次读取都会返回最新的数据。
  • 可用性(Availability):每个请求都会得到一个正常的响应,但响应可能不包含最新的数据。

对一个分布式(多节点)系统,如果它声称不需要分区容忍性,那它必须运行在一个保证不会有任何信息丢失或延时的网络上,并且它的所有结点都不会死亡。这种分布式系统是不存在的。因此CAP原则的本质是,当网络分区(即脑裂)发生时,分布式系统无法既保证一致性又保证可用性,必须选择牺牲其中一方。

CA Systems

严格来说这个分类并不存在,也可以假设永远可用的单机系统属于这个类别。

  • 单体SQL数据库 - 只适用于单机系统,因为它不是分布式系统。一旦有多节点参与,比如主从数据复制,读写分离等,都不属于CA系统。

CP Systems

通过取消请求来保护数据展示一致性,即使它降低了系统的可用性。这种系统称为CP系统。

  • MongoDB - 默认情况下,MongoDB是一个高度一致的系统。一旦写入完成,任何后续读取都将返回最新值。当对Secondary成员进行读取操作时,MongoDB成为最终一致的系统。
  • Redis -
  • Kafka - 通过参数配置以牺牲可用性来维持数据一致性:
    • unclean.leader.election.enable = false:如果所有ISR(in-sync replica)被分区,没有其他replica能被选举成为leader,该topic partition不可用。
    • min.insync.replicas,replication.factoracks:只有当ISR的个数高于min.insync.replicas时,topic partition才会接受写入。如果Producer设置成acks=all,则当所有ISR都成功写入才发送ack给Producer。要维持数据一致性,min.insync.replicas要配置成占replication.factor大多数。

AP Systems

即使可能返回不一致的数据,也要提供可用性。这些系统是AP分布式系统。

  • Cassandra - 默认情况下,Cassandra是一个最终一致的系统。一旦写入完成,只要不进行后续更改,最新数据最终就会可用。Cassandra可以通过调节一致性和可用性模型来达到强一致性。
  • Kafka - 通过参数配置以牺牲一致性换取可用性,但Kafka并不支持最终一致性(因为Consumer只会从ISR中消费),所以只适用于完全不在乎数据一致性的场景,如处理日志:
    • unclean.leader.election.enable = true:任何一个replica都可以被选举成leader,即使它不是ISR,所以topic partition一直可用。
    • Producer使用acks=0/1:不在乎写入是否成功。

参考资料

  • https://everybit.cloud/data-and-databases/
  • https://zhuanlan.zhihu.com/p/394160966
  • https://www.baeldung.com/cs/saga-pattern-microservices
  • https://codahale.com/you-cant-sacrifice-partition-tolerance/