kafka如何处理网络分区?

时间:2018-02-16 11:25:26

标签: apache-kafka consensus

Kafka有一个同步副本集的概念,这是一组节点,它们并不落后于领导者。

如果网络干净地进行分区以使得包含领导者的少数群体位于一侧,而大多数群体包含另一侧的其他同步节点,会发生什么?

少数派/领导者可能认为它丢失了一堆节点,相应地减少了ISR大小,并愉快地继续进行。

另一方可能认为它失去了领导者,所以它选择了一个新的并且愉快地继续。

现在我们在同一个集群中有两个领导者,独立接受写入。在需要大多数节点在分区之后继续运行的系统中,旧的领导者将下台并停止接受写入。

卡夫卡在这种情况下会发生什么?是否需要多数投票才能更改ISR设置?如果是这样,在领导者侧检测到中断之前是否会有短暂的数据丢失?

2 个答案:

答案 0 :(得分:6)

在Kafka集群中,其中一个经纪人被选为控制人。

除其他外,控制人负责选举新领导人。副本管理部分简要介绍了这一点:http://kafka.apache.org/documentation/#design_replicamanagment

Kafka使用Zookeeper尝试确保一次只有一个控制器。但是,您描述的情况仍然可能发生,将Zookeeper集合(假设双方仍然具有仲裁)和2中的Kafka集群分开,从而产生2个控制器。

在这种情况下,Kafka有许多配置来限制影响:

  • unclean.leader.election.enable:默认情况下为false,用于防止非同步的副本成为领导者。如果没有可用的副本同步,则Kafka会将分区标记为脱机,从而防止数据丢失
  • replication.factormin.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条记录,并且在分区修复后,它们将从前领导者处被删掉。

比方说,您期望更长的网络分区比对只读感到满意的时间。

类似的东西可以工作:

  • 您有3个可用区,并希望最多将1个区与其他2个区进行分区
  • 在每个区域中,您都有一个Zookeeper节点(或几个),因此,合并的2个区域始终可以构成多数
  • 在每个区域中,都有一堆Kafka经纪人
  • 每个主题都有replication.factor = 3,每个可用区中有一个副本min.insync.replicas = 2
  • 生产者的acks = all

这样,在网络分区的ZK仲裁端应有两个Kafka ISR,其中至少一个与前领导者完全一致。因此,经纪人不会丢失任何数据,并且可以从仍然能够连接到获胜方的任何生产者处进行写操作。