2015-06-17 62 views
22

我能夠在一臺linux機器上本地獲得一個簡單的單節點Kafka(kafka_2.11-0.8.2.1),但是當我嘗試運行一名製作人遠程我收到一些令人困惑的錯誤。Kafka QuickStart,advertised.host.name給出了kafka.common.LeaderNotAvailableException

我按照http://kafka.apache.org/documentation.html#quickstart的快速入門指南。我停止了kafka進程,並刪除了/ tmp中的所有動物園管理員karma文件。我在本地網絡10.0.0.0/24 NAT-ED與外部的IP地址,所以我修改server.properties告訴飼養員如何播放我的外部地址,按https://medium.com/@thedude_rog/running-kafka-in-a-hybrid-cloud-environment-17a8f3cfc284

advertised.host.name=MY.EXTERNAL.IP 

然後我跑這樣的:

$ bin/zookeeper-server-start.sh config/zookeeper.properties 
--> ... 
$ export KAFKA_HEAP_OPTS="-Xmx256M -Xms128M" # small test server! 
$ bin/kafka-server-start.sh config/server.properties 
--> ... 

我打開了防火牆,我在遠程機器上生產,並創造了一個新的話題,並加以驗證:

$ bin/kafka-topics.sh --create --zookeeper MY.EXTERNAL.IP:2181 --replication-factor 1 --partitions 1 --topic test123 
--> Created topic "test123". 
$ bin/kafka-topics.sh --list --zookeeper MY.EXTERNAL.IP:2181 
--> test123 

但是,製片人我飛奔克遠程給我錯誤:

$ bin/kafka-console-producer.sh --broker-list MY.EXTERNAL.IP:9092 --topic test123 
--> [2015-06-16 14:41:19,757] WARN Property topic is not valid (kafka.utils.VerifiableProperties) 
My Test Message 
--> [2015-06-16 14:42:43,347] WARN Error while fetching metadata [{TopicMetadata for topic test123 -> 

無分區的元數據爲主題test123由於kafka.common.LeaderNotAvailableException}]爲主題[test123]:類kafka.common.LeaderNotAvailableException(kafka.producer.BrokerPartitionInfo) - >(反覆幾次)

(我禁用了整個防火牆,以確保沒有問題)

在卡瑪 - 啓動標準輸出錯誤重複:[2015-06-16 20:42:42,768] INFO Closing socket connection to /MY.EXTERNAL.IP. (kafka.network.Processor)

而controller.log給我這個,好幾次:

java.nio.channels.ClosedChannelException 
    at kafka.network.BlockingChannel.send(BlockingChannel.scala:100) 
    at kafka.controller.RequestSendThread.liftedTree1$1(ControllerChannelManager.scala:132) 
    at kafka.controller.RequestSendThread.doWork(ControllerChannelManager.scala:131) 
    at kafka.utils.ShutdownableThread.run(ShutdownableThread.scala:60) 
[2015-06-16 20:44:08,128] INFO [Controller-0-to-broker-0-send-thread], Controller 0 connected to id:0,host:MY.EXTERNAL.IP,port:9092 for sending state change requests (kafka.controller.RequestSendThread) 
[2015-06-16 20:44:08,428] WARN [Controller-0-to-broker-0-send-thread], Controller 0 epoch 1 fails to send request Name:LeaderAndIsrRequest;Version:0;Controller:0;ControllerEpoch:1;CorrelationId:7;ClientId:id_0-host_null-port_9092;Leaders:id:0,host:MY.EXTERNAL.IP,port:9092;PartitionState:(test123,0) -> (LeaderAndIsrInfo:(Leader:0,ISR:0,LeaderEpoch:0,ControllerEpoch:1),ReplicationFactor:1),AllReplicas:0) to broker id:0,host:MY.EXTERNAL.IP,port:9092. Reconnecting to broker. (kafka.controller.RequestSendThread) 

運行,這似乎表明,處於0的領先者:

$ ./bin/kafka-topics.sh --zookeeper MY.EXTERNAL.IP:2181 --describe --topic test123 
--> Topic:test123 PartitionCount:1 ReplicationFactor:1 Configs: 
Topic: test123 Partition: 0 Leader: 0 Replicas: 0 Isr: 0 

我重新這個測試我的server.log指示有0的領先者:

... 
[2015-06-16 21:58:04,498] INFO 0 successfully elected as leader (kafka.server.ZookeeperLeaderElector) 
[2015-06-16 21:58:04,642] INFO Registered broker 0 at path /brokers/ids/0 with address MY.EXTERNAL.IP:9092. (kafka.utils.ZkUtils$) 
[2015-06-16 21:58:04,670] INFO [Kafka Server 0], started (kafka.server.KafkaServer) 
[2015-06-16 21:58:04,736] INFO New leader is 0 (kafka.server.ZookeeperLeaderElector$LeaderChangeListener) 

我看到在日誌這個錯誤,當我從生產者發送消息:

[2015-06-16 22:18:24,584] ERROR [KafkaApi-0] error when handling request Name: TopicMetadataRequest; Version: 0; CorrelationId: 7; ClientId: console-producer; Topics: test123 (kafka.server.KafkaApis) 
kafka.admin.AdminOperationException: replication factor: 1 larger than available brokers: 0 
    at kafka.admin.AdminUtils$.assignReplicasToBrokers(AdminUtils.scala:70) 

我認爲這意味着經紀人不能出於某種原因?我很困惑這意味着什麼......

+0

我以前有過這個。我們在我們的主題上設置了複製因子3,並且有3個經紀人,但是我們的一個經紀人沒有工作,因爲我們不小心給了它與其他經紀人相同的經紀人ID。我們更改了經紀人ID並重新啓動,這解決了問題。 –

+0

@JonHunter這很奇怪,因爲我只有一個經紀人和一個主題。我在昨晚的EC2上設置了相同的方式,看看它是否與我的託管設置有關,但我也有同樣的錯誤。 – mikebridge

+0

您可以嘗試更改您的經紀人ID。我之前沒有使用過0的代理ID(即使Kafka文檔說可以)。您也可以使用Zookeeper客戶端「zkCli.sh」,它將向您顯示哪些代理已在Zookeeper中註冊(它允許您瀏覽Zookeeper znode結構)。 –

回答

14

所以總結,解決,這是通過NAT添加路由,使機器可以訪問自己的外部IP地址。

Zookeeper使用它在advertised.host中找到的地址。既要告訴客戶在哪裏尋找經紀人,又要與經紀人本身溝通。獲得報告的錯誤並沒有使這一點變得非常清楚,並且令人困惑,因爲客戶端打開TCP連接沒有問題。

+1

如果您使用多個代理(=在相同的廣告主機名後面運行多個kafka容器),這樣做會工作嗎? – keftes

1

在安裝了Kafka的機器上,檢查它是否已啓動並正在運行。錯誤狀態,0經紀人可用,這意味着卡夫卡沒有啓動和運行。

在Linux機器上,您可以使用netstat命令來檢查服務是否正在運行。

的netstat -an | grep的port_kafka_is_Listening(默認爲9092)

+0

是的,它確實在運行並在端口9092上偵聽。我可以連接到kafka,沒有任何問題,只是當我生成消息時,它會在生產者和服務器上給我提供錯誤。在EC2上重現此錯誤很容易。 – mikebridge

20

將advertised.host.name設置爲主機名稱,而不是IP地址。缺省情況下,使用getCanonicalHostName()返回FQDN,但這只是盡力而爲並回退到IP。請參閱java docs for getCanonicalHostName()

訣竅是讓該主機名始終解析爲正確的IP。對於小型環境,我通常在/ etc/hosts中設置所有主機及其所有內部IP。通過這種方式,所有機器都知道如何通過名稱在內部網絡上相互交談。事實上,現在也可以按名稱配置您的Kafka客戶端,而不是通過IP。如果管理所有/ etc/hosts文件是一項負擔,那麼請設置一個內部DNS服務器以集中它,,但內部DNS應返回內部IP。這些選項中的任何一個都不應該比分佈在各種機器上的各種配置文件中的IP地址要少。

一旦所有事情都按名稱進行通信,剩下的就是使用外部IP配置外部DNS,並且一切正常。這包括使用服務器名稱配置Kafka客戶端,而不是IP。

5

從上面提示:對於我的單個節點(雖然仍在學習)我修改了server.properties文件,文本爲「advertised.host.name」value=127.0.01。所以最後它看起來像這樣

advertised.host.name = 127.0.0.1

雖然開始生產它仍然顯示警告,但現在它ATLEAST工作時,我可以看到消費終端上的消息完全來臨

20

對於最新版本的Kafka(截至撰寫本文時爲0.10.0),您根本不想使用advertised.host.name。實際上,即使[文檔]指出advertised.host.name已被棄用。此外,卡夫卡不僅將其用作生產者/消費者的「廣告主」名稱,還將用於其他經紀商(在多經紀商環境中)......如果您是爲經紀人使用不同的(也許是內部的)DNS ...並且你真的不想進入將經紀人添加到個人/etc/hosts的業務(ew!)

因此,基本上,你會希望經紀人使用內部名稱,但對生產者和消費者使用外部FQDN 只有。爲此,您將更新advertised.listeners

+0

http://kafka.apache.org/documentation.html#brokerconfigs – donaldh

0

conf/server.properties: host.name DEPRECATED:僅當未設置listeners時才使用。改爲使用listeners。經紀人的主機名。如果設置了,它只會綁定到這個地址。如果沒有設置,它將綁定到所有接口