kafka如何处理网络分区?
How does kafka handle network partitions?
Kafka 有一个同步副本集的概念,它是一组不落后于领导者太远的节点。
如果网络完全划分,使得包含领导者的少数在一侧,而包含其他同步节点的多数在另一侧,会发生什么情况?
minority/leader-side大概是认为自己丢了一堆节点,相应地减小了ISR的大小,然后愉快的进行下去。
对方可能认为自己失去了leader,于是重新选了一个leader,愉快的进行下去。
现在我们在同一个集群中有两个领导者,独立接受写入。在需要大多数节点在分区后继续进行的系统中,旧领导者将下台并停止接受写入。
在 Kafka 中,这种情况会发生什么?是否需要多数投票才能更改 ISR 集?如果是这样,在领导方检测到中断之前是否会出现短暂的数据丢失?
在 Kafka 集群中,其中一个代理被选为控制器。
除其他事项外,控制器负责选举新的领导者。副本管理部分对此进行了简要介绍:http://kafka.apache.org/documentation/#design_replicamanagment
Kafka 使用 Zookeeper 来尝试确保一次只有 1 个控制器。但是,您描述的情况仍然可能发生,将 Zookeeper 集群(假设双方仍然可以拥有法定人数)和 Kafka 集群分成 2 个,从而产生 2 个控制器。
在那种情况下,Kafka 有一些配置来限制影响:
unclean.leader.election.enable
:默认为 false,这用于防止不是 in-sync 的副本成为领导者。如果没有可用的副本in-sync,Kafka 将分区标记为离线,防止数据丢失
replication.factor
和min.insync.replicas
:比如分别设置为3和2,在"split-brain"的情况下可以防止生产者向少数派发送记录如果他们使用 acks=all
另请参阅 KIP-101 以了解有关处理集群重新组合后发生分歧的日志的详细信息。
我没有对此进行测试,但我认为公认的答案是错误的,而 Lars Francke 对脑裂可能性的看法是正确的。
Zookeeper quorum 需要多数,所以如果 ZK 集成分区,最多一侧会有一个 quorum。
作为控制器需要与 ZK(临时 znode 注册)进行活动会话。如果当前控制器与 ZK quorum 分开,它应该自动停止将自己视为控制器。这最多需要 zookeeper.session.timeout.ms = 6000
。仍然连接到 ZK quorum 的经纪人应该在他们之间选举一个新的控制器。 (基于此:)
成为主题分区领导者还需要与 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 超时 window 期间,分区前领导者收到的生产者请求会发生什么情况?有一些可能性。
如果生产者的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,其中至少一个与前领导者完全同步。因此,代理上没有数据丢失,并且可用于仍然能够连接到获胜方的任何生产者的写入。
Kafka 有一个同步副本集的概念,它是一组不落后于领导者太远的节点。
如果网络完全划分,使得包含领导者的少数在一侧,而包含其他同步节点的多数在另一侧,会发生什么情况?
minority/leader-side大概是认为自己丢了一堆节点,相应地减小了ISR的大小,然后愉快的进行下去。
对方可能认为自己失去了leader,于是重新选了一个leader,愉快的进行下去。
现在我们在同一个集群中有两个领导者,独立接受写入。在需要大多数节点在分区后继续进行的系统中,旧领导者将下台并停止接受写入。
在 Kafka 中,这种情况会发生什么?是否需要多数投票才能更改 ISR 集?如果是这样,在领导方检测到中断之前是否会出现短暂的数据丢失?
在 Kafka 集群中,其中一个代理被选为控制器。
除其他事项外,控制器负责选举新的领导者。副本管理部分对此进行了简要介绍:http://kafka.apache.org/documentation/#design_replicamanagment
Kafka 使用 Zookeeper 来尝试确保一次只有 1 个控制器。但是,您描述的情况仍然可能发生,将 Zookeeper 集群(假设双方仍然可以拥有法定人数)和 Kafka 集群分成 2 个,从而产生 2 个控制器。
在那种情况下,Kafka 有一些配置来限制影响:
unclean.leader.election.enable
:默认为 false,这用于防止不是 in-sync 的副本成为领导者。如果没有可用的副本in-sync,Kafka 将分区标记为离线,防止数据丢失replication.factor
和min.insync.replicas
:比如分别设置为3和2,在"split-brain"的情况下可以防止生产者向少数派发送记录如果他们使用acks=all
另请参阅 KIP-101 以了解有关处理集群重新组合后发生分歧的日志的详细信息。
我没有对此进行测试,但我认为公认的答案是错误的,而 Lars Francke 对脑裂可能性的看法是正确的。
Zookeeper quorum 需要多数,所以如果 ZK 集成分区,最多一侧会有一个 quorum。
作为控制器需要与 ZK(临时 znode 注册)进行活动会话。如果当前控制器与 ZK quorum 分开,它应该自动停止将自己视为控制器。这最多需要 zookeeper.session.timeout.ms = 6000
。仍然连接到 ZK quorum 的经纪人应该在他们之间选举一个新的控制器。 (基于此:
成为主题分区领导者还需要与 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 超时 window 期间,分区前领导者收到的生产者请求会发生什么情况?有一些可能性。
如果生产者的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,其中至少一个与前领导者完全同步。因此,代理上没有数据丢失,并且可用于仍然能够连接到获胜方的任何生产者的写入。