kafka客户端正在将请求发送到发生故障的代理所在的分区
我正在使用kafka-node模块将消息发送到kafka。在集群环境中,我的主题有3个分区,复制因子为3。
主题描述为-
Topic:clusterTopic PartitionCount:3 ReplicationFactor:3 Configs:min.insync.replicas=2,segment.bytes=1073741824
Topic: clusterTopic Partition: 0 Leader: 1 Replicas: 1,2,3 Isr: 1,2,3
Topic: clusterTopic Partition: 1 Leader: 2 Replicas: 2,3,1 Isr: 1,2,3
Topic: clusterTopic Partition: 2 Leader: 3 Replicas: 3,1,2 Isr: 1,2,3
生产者配置-
"requireAcks": 1,
"attributes": 2,
"partitionerType": 2,
"retries": 2
[当我发送数据时,它像循环方式一样遵循分区类型为cyclic(2)
当我按照以下步骤操作时
- 获取连接到kafka:9092,kafka:9093的HighLevelProducer实例
- 发送消息
- 手动停止kafka-server:9092
- 尝试并通过HighLevelProducer发送另一条消息,并且send()将触发带有错误的回调:TimeoutError:请求在以下时间后超时30000ms
我期望的是,如果无法访问分区(由于代理关闭),生产者应该自动将数据发送到下一个可用分区,但是由于异常,我丢失了消息
回答如下:请发送引导服务器进行确认,但是根据您所掌握的信息,我相信您的经历如下:
- 您的最小异步复制副本设置为2
- 您的臀部设置为1
使用这些设置,生产者将事件发送到领导者副本并假定消息是安全的。
如果它在发送后立即失败,并且在追随者赶上之前失败,则您将丢失消息,因为您仅在等待一个确认。
但是,从代理的角度来看,您要指定主题可用的要求是2个同步副本。默认情况下,仅允许同步副本被选为领导者。由于第一个失败会导致关注者不同步,因此您的主题可能被迫离线。您可以通过一些设置在测试中验证这一点。
要纠正,请尝试以下操作:
- 如果高可用性最重要,则将min.insync.replicas设置为1,将acks设置为1
- 如果无法接受数据丢失,则将min.insync.replicas设置为2,将acks设置为all]
您还可以将unclean.leader.election.enable设置为true以实现高可用性,因为这将允许不同步的副本被选为领导者,但是有可能丢失数据。