卡夫卡为什么不继续为其中一个经纪人的失败而工作?

时间:2015-08-03 12:53:11

标签: apache-kafka

我的印象是,如果两个经纪人同步开启,我的kafka设置应该继续工作,即使其中一个经纪人失败了。

为了测试它我创建了一个名为topicname的新主题。其描述如下:

Topic:topicname    PartitionCount:1 ReplicationFactor:1 Configs:
Topic: topicname    Partition: 0    Leader: 0   Replicas: 0 Isr: 0

然后我按以下方式运行producer.sh和consumer.sh:

bin/kafka-console-producer.sh --broker-list localhost:9092,localhost:9095 sync --topic topicname

bin/kafka-console-consumer.sh --zookeeper localhost:2181 --topic topicname --from-beginning

直到两个经纪人都在工作我才看到消费者正在正确接收消息,但是当我通过kill命令杀死其中一个经纪人实例时,消费者就停止向我显示任何新消息。相反,它向我显示以下错误消息:

WARN [ConsumerFetcherThread-console-consumer-57116_ip-<internalipvalue>-1438604886831-603de65b-0-0], Error in fetch Name: FetchRequest; Version: 0; CorrelationId: 865; ClientId: console-consumer-57116; ReplicaId: -1; MaxWait: 100 ms; MinBytes: 1 bytes; RequestInfo: [topicname,0] -> PartitionFetchInfo(9,1048576). Possible cause: java.nio.channels.ClosedChannelException (kafka.consumer.ConsumerFetcherThread)
[2015-08-03 12:29:36,341] WARN Fetching topic metadata with correlation id 1 for topics [Set(topicname)] from broker [id:0,host:<hostname>,port:9092] failed (kafka.client.ClientUtils$)
java.nio.channels.ClosedChannelException
at kafka.network.BlockingChannel.send(BlockingChannel.scala:100)
at kafka.producer.SyncProducer.liftedTree1$1(SyncProducer.scala:73)
at kafka.producer.SyncProducer.kafka$producer$SyncProducer$$doSend(SyncProducer.scala:72)
at kafka.producer.SyncProducer.send(SyncProducer.scala:113)
at kafka.client.ClientUtils$.fetchTopicMetadata(ClientUtils.scala:58)
at kafka.client.ClientUtils$.fetchTopicMetadata(ClientUtils.scala:93)
at kafka.consumer.ConsumerFetcherManager$LeaderFinderThread.doWork(ConsumerFetcherManager.scala:66)
at kafka.utils.ShutdownableThread.run(ShutdownableThread.scala:60)

5 个答案:

答案 0 :(得分:3)

我有类似的问题,设置了生产者配置&#34; topic.metadata.refresh.interval.ms&#34;到-1(或任何适合你的价值)为我解决了这个问题。 所以在我的情况下,我有3个代理(在我的本地机器上设置多个代理)并创建了3个分区和复制因子2的主题。

测试设置:

在制作人配置之前:

尝试了3个经纪人运行,在生产者启动后杀死了其中一个经纪人,当地Zookeeper更新了ISR和主题元数据信息(删除了经纪人作为领导者),但生产者没有拿起它(可能是默认10分钟)刷新时间)。所以消息最终失败。我收到了发送例外情况。

在生成器配置之后(在我的情况下为-1):

尝试了3个代理运行,在生产者启动后杀死了其中一个代理,本地Zookeeper更新了ISR信息(删除了代理作为领导者),生产者刷新了新的ISR /主题元数据信息并且消息发送没有失败。 / p>

-1使它在每次失败尝试时刷新主题元数据,因此您可能希望将刷新时间减少到合理的范围。

答案 1 :(得分:2)

您可以在主题说明中看到您发布的主题只有一个副本。 使用单个副本时,没有容错,如果代理0(包含副本的代理)消失,则主题将不可用。

创建一个包含更多副本(包含--replication-factor 3)的主题,以便在发生崩溃时具有容错能力。

答案 2 :(得分:2)

我认为有两件事情可以让你的消费者在代理kafka HA集群之后无法工作:

  1. - 对于您的主题,复制因子应大于1。所以每个主题分区至少可以有一个备份。

  2. kafka配置的内部主题的复制因子也应大于1:

    offsets.topic.replication.factor = 3

    transaction.state.log.replication.factor = 3

    transaction.state.log.min.isr = 2

  3. 这两个修改使我的生产者和消费者在经纪人关闭后仍然工作(5经纪人和每个经纪人一次倒闭)。

答案 3 :(得分:1)

即使使用复制因子为2的主题,我也遇到了同样的问题。 在制作人上设置以下属性对我有用。 &#34; metadata.max.age.ms&#34 ;. (卡夫卡0.8.2.1)

否则,我的制作人默认等待1分钟,以获取新的领导者并开始联系

答案 4 :(得分:0)

对于复制因子为N的主题,Kafka最多可容忍N-1个服务器故障。例如。拥有复制因子3将允许您处理最多2个服务器故障。