Kafka有一个同步副本集的概念,这是一组节点,它们并不落后于领导者。
如果网络干净地进行分区以使得包含领导者的少数群体位于一侧,而大多数群体包含另一侧的其他同步节点,会发生什么?
少数派/领导者可能认为它丢失了一堆节点,相应地减少了ISR大小,并愉快地继续进行。
另一方可能认为它失去了领导者,所以它选择了一个新的并且愉快地继续。
现在我们在同一个集群中有两个领导者,独立接受写入。在需要大多数节点在分区之后继续运行的系统中,旧的领导者将下台并停止接受写入。
卡夫卡在这种情况下会发生什么?是否需要多数投票才能更改ISR设置?如果是这样,在领导者侧检测到中断之前是否会有短暂的数据丢失?
答案 0 :(得分:6)
在Kafka集群中,其中一个经纪人被选为控制人。
除其他外,控制人负责选举新领导人。副本管理部分简要介绍了这一点:http://kafka.apache.org/documentation/#design_replicamanagment
Kafka使用Zookeeper尝试确保一次只有一个控制器。但是,您描述的情况仍然可能发生,将Zookeeper集合(假设双方仍然具有仲裁)和2中的Kafka集群分开,从而产生2个控制器。
在这种情况下,Kafka有许多配置来限制影响:
unclean.leader.election.enable
:默认情况下为false,用于防止非同步的副本成为领导者。如果没有可用的副本同步,则Kafka会将分区标记为脱机,从而防止数据丢失replication.factor
和min.insync.replicas
:例如,如果将它们分别设置为3和2,如果出现“裂脑”,则可以阻止生产者向少数派发送记录使用acks=all
另请参阅KIP-101,了解有关处理群集重新组合后已分歧的日志的详细信息。
答案 1 :(得分:1)
我还没有对此进行测试,但是我认为公认的答案是错误的,拉斯·弗兰克在脑裂的可能性上是正确的。
Zookeeper法定人数占多数,因此,如果ZK整体分区最多只有一个法定人数。
要成为控制器,需要与ZK(临时znode注册)进行活动会话。如果当前控制器的分区远离ZK仲裁,则应自愿停止将自己视为控制器。这最多需要zookeeper.session.timeout.ms = 6000
。仍与ZK仲裁连接的经纪人应在他们之间选举一个新的控制者。 (基于此:https://stackoverflow.com/a/52426734)
要成为主题分区负责人,还需要与ZK进行积极的对话。与ZK仲裁失去联系的领导者应自愿停止成为一个领导者。当选的控制器将检测到某些前领导者缺失,并将从ISR中分配新的领导者,并仍与ZK仲裁保持联系。
现在,在ZK超时窗口期间,分区前领导收到的生产者请求会如何处理?有可能。
如果生产者的acks = all
和主题的min.insync.replicas = replication.factor
,则所有ISR都应具有完全相同的数据。前领导最终将拒绝进行中的写入,而制作人将重试它们。新当选的领导人将不会丢失任何数据。另一方面,直到分区修复后,它才能处理任何写请求。生产者可以决定拒绝客户请求或在后台重试一段时间。
否则,新领导者很可能会丢失多达zookeeper.session.timeout.ms + replica.lag.time.max.ms = 16000
条记录,并且在分区修复后,它们将从前领导者处被删掉。
比方说,您期望更长的网络分区比对只读感到满意的时间。
类似的东西可以工作:
replication.factor = 3
,每个可用区中有一个副本min.insync.replicas = 2
acks = all
这样,在网络分区的ZK仲裁端应有两个Kafka ISR,其中至少一个与前领导者完全一致。因此,经纪人不会丢失任何数据,并且可以从仍然能够连接到获胜方的任何生产者处进行写操作。