kafka怎么实现CAP

最后更新:2020-02-07

1. CP

如果想实现Kafka配置为 CP系统, 配置需要如下:

request.required.acks=-1
min.insync.replicas = ${N/2 + 1}
unclean.leader.election.enable = false

如图所示,在acks=-1 的情况下,新消息只有被ISR中的所有 follower(f1和f2, f3) 都从leader复制过去才会回ack, ack后,无论那种机器故障情况(全部或部分), 写入的msg4,都不会丢失, 消息状态满足一致性C 要求。

正常情况下,所有follower复制完成后,leader回producer ack。

异常情况下,如果当数据发送到 leader后部分副本(f1和f2同步), leader挂了?此时任何 follower 都有可能变成新的 leader, producer 端会得到返回异常,producer 端会重新发送数据,但这样数据可能会重复(但不会丢失), 暂不考虑数据重复的情况。

min.insync.replicas 参数用于保证当前集群中处于正常同步状态的副本follower数量,当实际值小于配置值时,集群停止服务。如果配置为 N/2+1, 即多一半的数量,则在满足此条件下,通过算法保证强一致性。当不满足配置数时,牺牲可用性即停服。

异常情况下,leader挂掉,此时需要重新从follower选举leader。可以为f2或者f3。

如果选举f3为新leader, 则可能会发生消息截断,因为f3还未同步msg4的数据。Kafka通过unclean.leader.election.enable来控制在这种情况下,是否可以选举f3为leader。旧版本中默认为true,在某个版本下已默认为false,避免这种情况下消息截断的出现。

通过ack和min.insync.replicas和unclean.leader.election.enable的配合,保证在Kafka配置为CP系统时,要么不工作,要么得到ack后,消息不会丢失且消息状态一致。

2. AP

如果想实现Kafka配置为AP(Availability & Partition tolerance)系统:

request.required.acks=1
min.insync.replicas = 1
unclean.leader.election.enable = false

当配置为acks=1 时,即leader接收消息后回ack,这时会出现消息丢失的问题:如果 leader接受到了 第4 条消息,此时还没有同步到 follower中,leader机器挂了,其中一个follower被选为 leader, 则 第 4 条消息丢失了。

当然这个也需要unclean.leader.election.enable参数配置为false来配合。但是leader回ack的情况下,follower未同步的概率会大大提升。

通过producer策略的配置和Kafka集群通用参数的配置,可以针对自己的业务系统特点来进行合理的参数配置,在通讯性能和消息可靠性下寻得某种平衡。

3. 参考资料

https://mp.weixin.qq.com/s/Tmdq5VwLd48OaURMjG8Wyw

Edgar

Edgar
一个略懂Java的小菜比