Kafkaプロデューサーおよびコンシューマー(0.9.0)スクリプトを使用してトピックからメッセージをプッシュ/プルしようとすると、以下のエラーが発生します。
[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$1(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マシン(boot2docker)IPアドレス:192.168.99.100
ZooKeeperポート:2181
Kafkaポート: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つのパーティションとレプリケーション係数1のトピックを既に作成しました。
リーダーの指定はであることに注意してください。これは、問題の一部である可能性があります。
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など)を使用しているため、boot2dockerがホストVMに自動マウントする/Users/
パスを介してマウントする必要があります。基盤となるVM自体がバインドマウントを使用するため、KafkaのI/Oエンジンはそれと正しく通信できませんでした。ボリュームマウントがホストLinux上のディレクトリに直接行われた場合VM(つまり、boot2dockerマシン)は機能します。
Kafka I/Oの詳細がわからないため、正確な詳細を説明することはできませんが、マウントされたボリュームをMacファイルシステムに削除すると機能します。