关于CAP理论的介绍,其实网上已经有很多文章,大家可以自行查阅。这篇文章尝试从Kafka的角度来分析CAP理论。



0

CAP理论,有人把它翻译成中文叫“帽子理论”,是Eric Brewer在1998年提出来的一个约束分布式存储系统的理论。


CAP是Consistency、Availability和Partition tolerance三个单词的首字母缩写,这三个单词分别指代数据强一致性/线性一致性、系统整体可用性和网络分区容忍性。这个理论指出,任何一个分布式存储系统至多只能同时满足这三个特性中的两个,比如CA、CP或者AP。


Partition tolerance(网络分区容忍性),和我们经常听到的Fault tolerance(容错)、Latency tolerance(网络延迟容忍)类似,都是应用程序为了保持健壮性而对一些特定情况做的额外处理逻辑。所以,CP指的是,在有网络分区容忍处理的前提下,系统能够保证强一致性;AP系统指的是,在有网络分区容忍处理的前提下,系统能够保证整体可用性。


而CA系统指的是,系统保证强一致性和整体可用性,但是不保证Partition tolerance。这里“不保证Partition tolerance”,应该理解成“没有网络分区”还是“有网络分区,没有容忍机制”呢?网上有很多不同的观点:

观点一:理解成一个的操作范围,即CA是在没有网络分区的情况下的操作

观点二:牺牲一部分功能,比如写操作,以保证强一致性,但是似乎A受到了一定程度的影响

观点三:单机系统


但是,一般来讲,在现实情况下,网络分区是一定存在的,所以在系统实现的时候必须要考虑Partition tolerance,基于此,我们要实现的就是CP或者AP了。



1

Kafka,当今非常流行的一个高可用消息中间件open source。其实,就像其Logo中提到的,Kafka是一个分布式的流式计算机平台,只是说在很多场景下,我们只把它用作消息中间件。

浅谈CAP与Kafka-LMLPHP


那么,Kafka作为一个分布式消息中间件,满足CAP理论吗?如果满足的话,满足哪两个特性呢,CA、AP或者CP?


如果你在网上搜索Kafka CAP,你可能会发现Kafka的开发人员申明Kafka是CA系统。

浅谈CAP与Kafka-LMLPHP


原因是,Kafka设计是运行在一个数据中心,网络分区问题基本不会发生,所以是CA系统。


但是,现实情况是,即使运行在一个数据中心,网络问题理论上也是存在的,所以这是一个必须要考虑的点。那么,Kafka是AP还是CP系统呢?


其实,Kafka提供了一些配置,用户可以根据具体的业务需求,进行不同的配置,使得Kafka满足AP或者CP,或者它们之间的一种平衡。


比如下面这种配置,就保证强一致性,使得Kafka满足CP。任意写入一条数据,都需要等到replicate到所有节点之后才返回ack;接下来,在任意节点都可以消费到这条数据,即是在有节点宕机的情况下,包括主节点。


而下面的配置,就主要保证可用性,使得Kafka满足AP。对于任意写入一条数据,当主节点commmit了之后就返回ack;如果主节点在数据被replicate到从节点之前就宕机,这时,重新选举之后,消费端就读不到这条数据。这种配置,保证了availability,但是损失了consistency。


还有一种配置是公认比较推荐的一种配置,基于这种配置,损失了一定的consistency和availability,使得Kafka满足的是一种介于AP和CP之间的一种平衡状态。因为,在这种配置下,可以在容忍一个节点(包括主节点)宕机的情况下,任然保证数据强一致性和整体可用性;但是,有两个节点宕机的情况,就整体不可用了。

对于这种配置,其实Kafka不光可以容忍一个节点宕机,同时也可以容忍这个节点和其它节点产生网络分区,它们都可以看成是Kafka的容错(Fault tolerance)机制。


除了上面的几个常用配置项,下面这个配置项也跟consistency和availability相关。这个配置项的作用是控制,在所有节点宕机之后,如果有一个节点之前不是在ISR列表里面,启动起来之后是否可以成为leader。当设置成默认值false时,表示不可以,因为这个节点的数据很可能不是最新的,如果它成为了主节点,那么就可能导致一些数据丢失,从而损失consistency,但是却可以保证availability。如果设置成true,则相反。这个配置项让用户可以基于自己的业务需要,在consistency和availability之间做一个选择。


最后,其实不光是Kafka,还有很多其它的系统(特别是一些基于分布式共识算法的数据存储系统,比如:zookeeper),也不是严格的AP或者CP系统。所以,我们没有必要严格地用CAP来讨论或者以此为guideline来构建一个分布式存储系统,没有太大的意义。关于这一点,这里推荐两篇文章,大家可以参考:

https://martin.kleppmann.com/2015/05/11/please-stop-calling-databases-cp-or-ap.html

https://www.infoq.com/articles/cap-twelve-years-later-how-the-rules-have-changed/



2

除了Partition tolerance,我们可能还经常听到Fault tolerance(容错)和Latency tolerance(网络延迟容忍),它们其实都是指程序在应对某些情况时的容忍能力,从highlevel来讲,这是一个系统resilience的体现。比如Latency tolerance,当网络延迟比较大的时候,应用程序可以实现一些fallback逻辑,以此来提高用户的响应时间。对于应用程序端的容错处理,业界有一些很流行的open source,比如说Hystrix和resilience4j。

浅谈CAP与Kafka-LMLPHP




References

  • https://en.wikipedia.org/wiki/CAP_theorem

  • https://kafka.apache.org/documentation/

  • https://stackoverflow.com/questions/51375187/why-kafka-is-not-p-in-cap-theorem

  • https://aphyr.com/posts/293-jepsen-kafka


本文分享自微信公众号 - 天马行空布鲁斯(gh_2feda5c053bd)。
如有侵权,请联系 [email protected] 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

08-30 19:38