获取主题元数据时的 Kafka 消费者 "failed to find leader"
Kafka consumer "failed to find leader" when fetching topic metadata
当我尝试使用 Kafka 生产者和消费者 (0.9.0) 脚本来 push/pull 来自主题的消息时,出现以下错误。
生产者错误
[2016-01-13 02:49:40,078] ERROR Error when sending message to topic test with key: null, value: 11 bytes with error: Failed to update metadata after 60000 ms. (org.apache.kafka.clients.producer.internals.ErrorLoggingCallback)
消费者错误
> [2016-01-13 02:47:18,620] WARN
> [console-consumer-90116_f89a0b380f19-1452653212738-9f857257-leader-finder-thread],
> Failed to find leader for Set([test,0])
> (kafka.consumer.ConsumerFetcherManager$LeaderFinderThread)
> kafka.common.KafkaException: fetching topic metadata for topics
> [Set(test)] from broker
> [ArrayBuffer(BrokerEndPoint(0,192.168.99.100,9092))] failed at
> kafka.client.ClientUtils$.fetchTopicMetadata(ClientUtils.scala:73) at
> kafka.client.ClientUtils$.fetchTopicMetadata(ClientUtils.scala:94) at
> kafka.consumer.ConsumerFetcherManager$LeaderFinderThread.doWork(ConsumerFetcherManager.scala:66)
> at kafka.utils.ShutdownableThread.run(ShutdownableThread.scala:63)
> Caused by: java.io.EOFException at
> org.apache.kafka.common.network.NetworkReceive.readFromReadableChannel(NetworkReceive.java:83)
> at
> kafka.network.BlockingChannel.readCompletely(BlockingChannel.scala:129)
> at kafka.network.BlockingChannel.receive(BlockingChannel.scala:120)
> at kafka.producer.SyncProducer.liftedTree1(SyncProducer.scala:77)
> at
> kafka.producer.SyncProducer.kafka$producer$SyncProducer$$doSend(SyncProducer.scala:74)
> at kafka.producer.SyncProducer.send(SyncProducer.scala:119) at
> kafka.client.ClientUtils$.fetchTopicMetadata(ClientUtils.scala:59)
> ... 3 more
为什么会出现错误,我该如何解决?
配置
运行 Mac 上 Docker 个容器中的所有组件。 ZooKeeper 和 Kafka 运行 在单独的 Docker 容器中。
Docker Machine (boot2docker) IP 地址:192.168.99.100
ZooKeeper 端口:2181
卡夫卡端口:9092
Kafka 配置文件 server.properties
设置如下:
host.name=localhost
broker.id=0
port=9092
advertised.host.name=192.168.99.100
advertised.port=9092
命令
我从 kafka 服务器 Docker 容器中 运行 以下命令。我已经创建了一个包含一个分区且复制因子为 1 的主题。
请注意,领导者指定为 0,这可能是问题的一部分。
root@f89a0b380f19:/opt/kafka/dist# ./bin/kafka-topics.sh --zookeeper 192.168.99.100:2181 --topic test --describe
Topic:test PartitionCount:1 ReplicationFactor:1 Configs:
Topic: test Partition: 0 Leader: 0 Replicas: 0 Isr: 0
然后我执行以下操作来发送一些消息:
root@f89a0b380f19:/opt/kafka/dist# ./bin/kafka-console-producer.sh --broker-list 192.168.99.100:9092 --topic test
one message
two message
three message
four message
[2016-01-13 02:49:40,078] ERROR Error when sending message to topic test with key: null, value: 11 bytes with error: Failed to update metadata after 60000 ms. (org.apache.kafka.clients.producer.internals.ErrorLoggingCallback)
[2016-01-13 02:50:40,080] ERROR Error when sending message to topic test with key: null, value: 11 bytes with error: Failed to update metadata after 60000 ms. (org.apache.kafka.clients.producer.internals.ErrorLoggingCallback)
[2016-01-13 02:51:40,081] ERROR Error when sending message to topic test with key: null, value: 13 bytes with error: Failed to update metadata after 60000 ms. (org.apache.kafka.clients.producer.internals.ErrorLoggingCallback)
[2016-01-13 02:52:40,083] ERROR Error when sending message to topic test with key: null, value: 12 bytes with error: Failed to update metadata after 60000 ms. (org.apache.kafka.clients.producer.internals.ErrorLoggingCallback)
这是我用来尝试消费消息的命令,它会产生我在上面发布的消费者错误。
root@f89a0b380f19:/opt/kafka/dist# ./bin/kafka-console-consumer.sh --zookeeper 192.168.99.100:2181 --topic test --from-beginning
我已确认端口 2181
和 9092
已打开并可从 Kafka Docker 容器中访问:
root@f89a0b380f19:/# nc -z 192.168.99.100 2181; echo $?;
0
root@f89a0b380f19:/# nc -z 192.168.99.100 9092; echo $?;
0
解决方案完全不是我所期望的。错误消息与实际情况不符。
主要问题是将 Docker 中的日志目录挂载到我的本地文件系统。我的 docker run
命令使用卷挂载将容器中的 Kafka log.dir
文件夹挂载到主机 VM 上的本地目录,该目录实际上已挂载到我的 Mac。问题是后一点。
例如,
docker run --name kafka -v /Users/<me>/kafka/logs:/var/opt/kafka:rw -p 9092:9092 -d kafka
因为我在 Mac 上并使用 docker-machine(例如 boot2docker),我必须通过我的 /Users/
路径挂载主机中的 boot2docker auto-mounts虚拟机。因为底层 VM 本身使用绑定挂载,Kafka 的 I/O 引擎无法与其正确通信。如果卷挂载直接挂载到主机 Linux VM(即 boot2docker 机器)上的目录,它就可以工作。
我无法解释确切的细节,因为我不知道 Kafka I/O 的 ins-and-outs,但是当我将挂载的卷删除到我的 Mac 文件系统时,它有效。
当我尝试使用 Kafka 生产者和消费者 (0.9.0) 脚本来 push/pull 来自主题的消息时,出现以下错误。
生产者错误
[2016-01-13 02:49:40,078] ERROR Error when sending message to topic test with key: null, value: 11 bytes with error: Failed to update metadata after 60000 ms. (org.apache.kafka.clients.producer.internals.ErrorLoggingCallback)
消费者错误
> [2016-01-13 02:47:18,620] WARN
> [console-consumer-90116_f89a0b380f19-1452653212738-9f857257-leader-finder-thread],
> Failed to find leader for Set([test,0])
> (kafka.consumer.ConsumerFetcherManager$LeaderFinderThread)
> kafka.common.KafkaException: fetching topic metadata for topics
> [Set(test)] from broker
> [ArrayBuffer(BrokerEndPoint(0,192.168.99.100,9092))] failed at
> kafka.client.ClientUtils$.fetchTopicMetadata(ClientUtils.scala:73) at
> kafka.client.ClientUtils$.fetchTopicMetadata(ClientUtils.scala:94) at
> kafka.consumer.ConsumerFetcherManager$LeaderFinderThread.doWork(ConsumerFetcherManager.scala:66)
> at kafka.utils.ShutdownableThread.run(ShutdownableThread.scala:63)
> Caused by: java.io.EOFException at
> org.apache.kafka.common.network.NetworkReceive.readFromReadableChannel(NetworkReceive.java:83)
> at
> kafka.network.BlockingChannel.readCompletely(BlockingChannel.scala:129)
> at kafka.network.BlockingChannel.receive(BlockingChannel.scala:120)
> at kafka.producer.SyncProducer.liftedTree1(SyncProducer.scala:77)
> at
> kafka.producer.SyncProducer.kafka$producer$SyncProducer$$doSend(SyncProducer.scala:74)
> at kafka.producer.SyncProducer.send(SyncProducer.scala:119) at
> kafka.client.ClientUtils$.fetchTopicMetadata(ClientUtils.scala:59)
> ... 3 more
为什么会出现错误,我该如何解决?
配置
运行 Mac 上 Docker 个容器中的所有组件。 ZooKeeper 和 Kafka 运行 在单独的 Docker 容器中。
Docker Machine (boot2docker) IP 地址:192.168.99.100
ZooKeeper 端口:2181
卡夫卡端口:9092
Kafka 配置文件 server.properties
设置如下:
host.name=localhost
broker.id=0
port=9092
advertised.host.name=192.168.99.100
advertised.port=9092
命令
我从 kafka 服务器 Docker 容器中 运行 以下命令。我已经创建了一个包含一个分区且复制因子为 1 的主题。
请注意,领导者指定为 0,这可能是问题的一部分。
root@f89a0b380f19:/opt/kafka/dist# ./bin/kafka-topics.sh --zookeeper 192.168.99.100:2181 --topic test --describe
Topic:test PartitionCount:1 ReplicationFactor:1 Configs:
Topic: test Partition: 0 Leader: 0 Replicas: 0 Isr: 0
然后我执行以下操作来发送一些消息:
root@f89a0b380f19:/opt/kafka/dist# ./bin/kafka-console-producer.sh --broker-list 192.168.99.100:9092 --topic test
one message
two message
three message
four message
[2016-01-13 02:49:40,078] ERROR Error when sending message to topic test with key: null, value: 11 bytes with error: Failed to update metadata after 60000 ms. (org.apache.kafka.clients.producer.internals.ErrorLoggingCallback)
[2016-01-13 02:50:40,080] ERROR Error when sending message to topic test with key: null, value: 11 bytes with error: Failed to update metadata after 60000 ms. (org.apache.kafka.clients.producer.internals.ErrorLoggingCallback)
[2016-01-13 02:51:40,081] ERROR Error when sending message to topic test with key: null, value: 13 bytes with error: Failed to update metadata after 60000 ms. (org.apache.kafka.clients.producer.internals.ErrorLoggingCallback)
[2016-01-13 02:52:40,083] ERROR Error when sending message to topic test with key: null, value: 12 bytes with error: Failed to update metadata after 60000 ms. (org.apache.kafka.clients.producer.internals.ErrorLoggingCallback)
这是我用来尝试消费消息的命令,它会产生我在上面发布的消费者错误。
root@f89a0b380f19:/opt/kafka/dist# ./bin/kafka-console-consumer.sh --zookeeper 192.168.99.100:2181 --topic test --from-beginning
我已确认端口 2181
和 9092
已打开并可从 Kafka Docker 容器中访问:
root@f89a0b380f19:/# nc -z 192.168.99.100 2181; echo $?;
0
root@f89a0b380f19:/# nc -z 192.168.99.100 9092; echo $?;
0
解决方案完全不是我所期望的。错误消息与实际情况不符。
主要问题是将 Docker 中的日志目录挂载到我的本地文件系统。我的 docker run
命令使用卷挂载将容器中的 Kafka log.dir
文件夹挂载到主机 VM 上的本地目录,该目录实际上已挂载到我的 Mac。问题是后一点。
例如,
docker run --name kafka -v /Users/<me>/kafka/logs:/var/opt/kafka:rw -p 9092:9092 -d kafka
因为我在 Mac 上并使用 docker-machine(例如 boot2docker),我必须通过我的 /Users/
路径挂载主机中的 boot2docker auto-mounts虚拟机。因为底层 VM 本身使用绑定挂载,Kafka 的 I/O 引擎无法与其正确通信。如果卷挂载直接挂载到主机 Linux VM(即 boot2docker 机器)上的目录,它就可以工作。
我无法解释确切的细节,因为我不知道 Kafka I/O 的 ins-and-outs,但是当我将挂载的卷删除到我的 Mac 文件系统时,它有效。