我们有一个 kafka 集群。还有一个网络。是的。由于维护需要,我们数据中心的所有机架上的网络将在 5-10 分钟内不可用(!)。我担心这个中断时间太长,kafka 无法妥善处理,而且它可能会开始对自己的状态感到困惑,以至于一旦网络恢复在线,它就无法恢复。
关闭集群是一个好主意吗?如果是的话,让所有代理离线的最佳方法是什么?
它是一个 kafka 0.10.0 集群,运行在数据中心不同机架分布的 6 个节点上。
答案1
关闭集群是个好主意吗
也许吧。这取决于您的耐久性要求,如果您能容忍从网络隔离中恢复时丢失数据。一定要确保您知道网络分区中系统会发生什么。
几年前,Jepsen 项目对 Kafka 进行了全面测试。 不干净的领导人选举是一个问题。单个同步副本 (ISR) 可以保持领先地位。如果最后一个 ISR 发生网络分区或死亡,剩余节点将选举新的领导者,从而导致数据丢失。我认为这在 0.11 版之前仍然是默认设置。
在网络事件发生之前完全关闭意味着不会因网络分区而出现不干净的领导者。查看controlled.shutdown.enable
和auto.leader.rebalance
选项以使分区迁移更容易。
要选择持久性,请考虑进行调整,以便通过将 acks 设置为“全部”,让大多数副本都能够确认写入。
当生产者将 acks 设置为“all”(或“-1”)时,min.insync.replicas 指定必须确认写入的最小副本数,写入才被视为成功。如果无法满足此最小值,则生产者将引发异常(NotEnoughReplicas 或 NotEnoughReplicasAfterAppend)。当一起使用时,min.insync.replicas 和 acks 允许您实施更高的持久性保证。典型的场景是创建一个复制因子为 3 的主题,将 min.insync.replicas 设置为 2,并使用 acks 进行生产“all”。这将确保如果大多数副本未收到写入,生产者将引发异常。
default.replication.factor=3
min.insync.replicas=2
# Default from 0.11.0
unclean.leader.election.enable=false
对于您当前的网络,如果您选择一致性,则将牺牲可用性。如果所有副本都无法相互通信,则无法获得大多数副本。此停机时间是否足以证明将集群分散到多个网络故障域是合理的,由您决定。
答案2
停电最终并没有我们想象的那么严重。
网络中断时集群仍处于运行状态。所有 kafka 客户端都已关闭,因此在中断之前集群处于安静状态。中断时间约为 3 分钟。恢复在线后,集群被允许重新聚合,似乎确实做到了这一点。请求了首选领导者选举,所有代理/所有主题都恢复了良好状态。稳定后,kafka 客户端重新上线,一切正常。
所以……对于这种情况,正确的做法是让 Kafka 集群安静下来,但不要关闭任何代理;让它继续运行——它会恢复的。当然,这假设您可以承受中断期间的数据丢失。