kafka如何处理网络分区?

Fil*_*und 8 consensus apache-kafka

Kafka有一个同步副本集的概念,它是一组不比领导者落后的节点.

如果网络干净地进行分区,以便包含领导者的少数人在一边,而大多数人包含另一边的其他同步节点,会发生什么?

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

另一方可能认为它失去了领导者,因此它选择了一个新领导者,并愉快地继续前进.

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

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

Mic*_*son 6

在Kafka集群中,选择了一个代理作为控制器。

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

Kafka使用Zookeeper来尝试确保一次只有1个控制器。但是,您描述的情况仍然可能发生,将Zookeeper集成(假设双方仍然可以达到法定人数)和Kafka群集拆分为2个,从而导致2个控制器。

在这种情况下,Kafka可以采用多种配置来限制影响:

  • unclean.leader.election.enable:默认为False,这用于防止与同步不同步的副本成为领导者。如果没有可用的副本处于同步状态,Kafka将分区标记为脱机,从而防止数据丢失
  • replication.factorand min.insync.replicas:例如,如果将它们分别设置为3和2,则在“裂脑”的情况下,如果生产者使用,则可以防止生产者向少数派发送记录acks=all

另请参阅KIP-101,以获取有关在群集恢复在一起后处理已分歧日志的详细信息。

  • 我不明白您如何拆分Zookeeper集合,并且仍然保持双方法定人数。 (2认同)

Ale*_*mov 6

我还没有测试过这个,但我认为接受的答案是错误的,而且 Lars Francke 关于大脑分裂的可能性是正确的。

Zookeeper quorum 需要多数,所以如果 ZK ensemble 分区,最多一侧会有一个 quorum。

作为控制器需要与 ZK(临时 znode 注册)进行活动会话。如果当前控制器与 ZK quorum 分开,它应该自动停止将自己视为控制器。这最多应该花费zookeeper.session.timeout.ms = 6000. 仍然连接到 ZK quorum 的 Broker 应该在他们之间选举一个新的控制器。(基于此:https : //stackoverflow.com/a/52426734

作为主题分区领导者还需要与 ZK 进行积极的会话。失去与 ZK quorum 连接的领导者应该自愿停止成为其中之一。Elected controller will detect that some ex-leaders are missing and will assign new leaders from the ones in ISR and still connected to ZK quorum.

现在,在 ZK 超时窗口期间,分区的前领导者收到的生产者请求会发生什么?有一些可能性。

如果是 producer'sacks = all和 topic's min.insync.replicas = replication.factor,那么所有的 ISR 应该有完全相同的数据。前领导者最终将拒绝正在进行的写入,生产者将重试它们。The newly elected leader will not have lost any data. 另一方面,在分区恢复之前,它将无法处理任何写入请求。由生产者决定拒绝客户端请求或在后台继续重试一段时间。

否则,很可能新的领导者将丢失足够多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,其中至少一个与前领导者完全同步。因此,代理上没有数据丢失,并且可供任何仍然能够连接到获胜方的生产者写入。