問題描述:kafka單台機器做集群操作是沒有問題的,如果分布多台機器並且partitions或者備份的個數大於1都會報kafka.common.KafkaException: Should not set log end offset on partition 這個錯誤,如果使用kafka默認的日志等級,過不了幾分鍾錯誤日志就會把磁盤刷滿,導致服務器down掉。
這個問題困擾了我幾天,怎么搞都不行,開始以為是版本問題,升級到最新版本問題還是存在,后來在官方FQA中找到了一段描述,原文如下:
Why do I see error "Should not set log end offset on partition" in the broker log?
Typically, you will see errors like the following.
kafka.common.KafkaException: Should not set log end offset on partition [test,22]'s local replica 4
ERROR [ReplicaFetcherThread-0-6], Error for partition [test,22] to broker 6:class kafka.common.UnknownException(kafka.server.ReplicaFetcherThread)
A common problem is that more than one broker registered the same host/port in Zookeeper. As a result, the replica fetcher is confused when fetching data from the leader. To verify that, you can use a Zookeeper client shell to list the registration info of each broker. The Zookeeper path and the format of the broker registration is described in Kafka data structures in Zookeeper. You want to make sure that all the registered brokers have unique host/port.
這段內容的大意思是不允許在zookeeper上注冊來自同一個主機+端口的brokers,開始我以為是同一台機器上掛了二個brokers的緣故,因為機器上我同時布署了solr與kafka,都用的同一個zookeeper服務,於是我把kafka的broker改成/chroot的方式,在zookeeper上加了一級節點:(原來的brokers寫法:192.168.12.206:2181,192.168.12.208:2181,改為:192.168.12.206:2181,192.168.12.208:2181/kafka)
經測試還是一樣的結果,我實在是沒撤了,最后我又仔細看了一下錯誤日志,發現一個規律,都是在分區備份的時候發生的此錯誤,所以我就在想是不是服務器之間數據同步有問題。
接着我打開kafka的配置文件,逐一往下看,發現了host.name屬性,我心中已經有一半相信是這個參數配置的問題,因為我沒有啟動這個參數,於是我把它改成實際的IP地址,如host.name=192.168.12.206,另一台也如是改,最后發現錯誤不報了,收發消息正常,於是我知道這個參數在默認不配置的時候,綁定的是當前主機127.0.0.1,所以集群中主機之間進行相互備份的時候通過127.0.0.1找不到主機了。
有二個方面的原因導致一直查不出問題,一是網上關於此問題的說明實在是少的可憐,有也都是千篇一律,查到的結果都一樣,另一個原因是配置文件的注釋讓人誤解,如host.name的注釋:
# Hostname the broker will bind to. If not set, the server will bind to all interfaces
從字面意思理解不就是“如果不設置,服務器將綁定到所有接口”,所以我想應該不設置也不會有問題。
這么簡單的問題,居然折騰了我幾天,所以寫出來,僅供參考。