通過之前的學習,我已經對Kafka有了初步的瞭解,這一篇是自己深入學習Kafka過程的記錄,主要包括單節點-多代理的配置、主題操作,以及在這些過程中經歷的報錯和解決方法,希望對和我一起學習Kafka的人有所幫助。
(一)單節點-多代理配置
1、啓動ZooKeeper
2、在Kafka的config目錄下新增多個代理文件
(1)複製粘貼server.properties,新增server-one.properties,server-one.properties兩個文件;
(2)修改新增的代理文件的配置:
config/server-one.properties
# The id of the broker. This must be set to a unique integer for each broker.
broker.id=1
# The address the socket server listens on. It will get the value returned from
# java.net.InetAddress.getCanonicalHostName() if not configured.
listeners=PLAINTEXT://:9093
# A comma separated list of directories under which to store log files
log.dirs=./logs-one
config/server-two.properties
# The id of the broker. This must be set to a unique integer for each broker.
broker.id=2
# The address the socket server listens on. It will get the value returned from
# java.net.InetAddress.getCanonicalHostName() if not configured.
listeners=PLAINTEXT://:9094
# A comma separated list of directories under which to store log files
log.dirs=./logs-two
3、啓動多個代理
Broker1
.\bin\windows\kafka-server-start.bat .\config\server.properties
Broker2
.\bin\windows\kafka-server-start.bat .\config\server-one.properties
Broker3
.\bin\windows\kafka-server-start.bat .\config\server-two.properties
4、新建主題
(1)先用命令行查看是不是有已創建的主題,我這裏還沒有創建主題,所以顯示沒有,如下圖所示:
(2)新建主題並查看
#新建示例
kafka-topics.bat --create --zookeeper localhost:2181 --topic TopicName
#查看主題列表示例
kafka-topics.bat --list --zookeeper localhost:2181
(3)不過上面都是隻創建了一個代理時的主題,如果有三個代理,這種怎麼辦呢?
只需要更改複製因子,也就是命令行“--replication-factor”後的數字,用“--describe”命令行去查看該主題的具體情況,如下圖所示:
#新建具有1個分區,3個複製因子的主題示例
kafka-topics.bat --create --zookeeper localhost:2181 --replication-factor 3 --partitions 1 --topic TopicName
#查看主題的具體信息
kafka-topics.bat --describe --zookeeper localhost:2181 --topic TopicName
以TestTopic4這個主題爲例:從上面的輸出中,我們看到第一行顯示了主題名稱,分區數和我們已經選擇的複製因子。在第二行中,每個節點將成爲分區的隨機選擇部分的領導者,而上面截圖中的領導者Leader都是broker.id=2的代理,zIsr副本是“2,0,1”。
5、創建生產者和消費者
創建生產者截圖如下:
創建消費者截圖如下:
如上面的截圖所示,可以看到我們的單節點多代理配置成功了。
(二)主題的更改、刪除
1、修改主題(增加分區數)
可以看到成功增加了一個分區,Partition Count:2
如果增加一個已有的分區會怎樣呢?我這裏就犯了這個錯誤:
結果提示我“執行topic命令時出錯:只能增加主題的分區數,主題TestTopic2當前有1個分區,分區1不能再次添加。”
2、刪除主題
示例:
kafka-topics.bat --describe --zookeeper localhost:2181 --topic TopicName
如上圖所示,實際上並沒有刪除那個主題,而只是做了個標記,而且也有句提醒在那裏:如果delete.topic.enable未設置爲true,則不會有任何影響。
此外,作爲領導者的Kafka代理(brokeris=2)報了異常結束,即使再次啓動這個Kafka代理也會報錯,所以刪主題前,記得備份Kafka和ZooKeeper的日誌。如果實在沒備份,可參照文末最後一條報錯記錄去解決。
不過,有人就會問了,到底怎麼徹底刪除Topic呢?
第一種方法是,找到server.propertise,搜索了一下delete.topic.enable,如果沒有這個配置,那麼添加一個並設置爲true,重新執行命令行去刪除Topic。
當然這種辦法可能還是不行,試試第二種辦法,具體步驟如下:
(1)找到zkCli.cmd,登錄zookeeper客戶端,下圖是登錄成功的截圖:
(2)執行命令行“ls /brokers/topics”,找到所有已創建的topic,輸出如下:
可以看到我已經創建的Topic:TestTopic, TestTopic1, TestTopic2, TestTopic3, TestTopic4。
(3)找到要刪除的topic,執行“deleteall /brokers/topics/topic名稱”即可,此時topic被徹底刪除:
不相信的話,可以執行查看主題列表的命令行去查看,如下圖所示:可以看到已經沒有TestTopic2這個主題了:
(三)報錯記錄
1、啓動Kafka報錯:
ERROR Fatal error during KafkaServer startup. Prepare to shutdown (kafka.server.KafkaServer)
kafka.common.InconsistentClusterIdException: The Cluster ID 7BxH6LhCQnGArxFtH5KAOw doesn't match stored clusterId Some(dIb7412LRPSDH3k0iA0GBw) in meta.properties. The broker is trying to join the wrong cluster. Configured zookeeper.connect may be wrong.
at kafka.server.KafkaServer.startup(KafkaServer.scala:220)
at kafka.server.KafkaServerStartable.startup(KafkaServerStartable.scala:44)
at kafka.Kafka$.main(Kafka.scala:84)
at kafka.Kafka.main(Kafka.scala)
報錯原因:修改了ZooKeeper的日誌路徑,但是沒刪除原來的日誌就啓動了Kafka。
解決辦法:刪除原來的ZooKeeper日誌,重新啓動Kafka。
2、啓動Kafka報錯:
ERROR [KafkaServer id=0] Fatal error during KafkaServer startup. Prepare to shutdown (kafka.server.KafkaServer)
org.apache.kafka.common.KafkaException: Failed to acquire lock on file .lock in D:\kafka_2.13-2.4.1\.\logs. A Kafka instance in another process or thread is using this directory.
at kafka.log.LogManager.$anonfun$lockLogDirs$1(LogManager.scala:249)
at scala.collection.StrictOptimizedIterableOps.flatMap(StrictOptimizedIterableOps.scala:118)
at scala.collection.StrictOptimizedIterableOps.flatMap$(StrictOptimizedIterableOps.scala:105)
at scala.collection.mutable.ArraySeq.flatMap(ArraySeq.scala:38)
at kafka.log.LogManager.lockLogDirs(LogManager.scala:244)
at kafka.log.LogManager.<init>(LogManager.scala:105)
at kafka.log.LogManager$.apply(LogManager.scala:1093)
at kafka.server.KafkaServer.startup(KafkaServer.scala:250)
at kafka.server.KafkaServerStartable.startup(KafkaServerStartable.scala:44)
at kafka.Kafka$.main(Kafka.scala:84)
at kafka.Kafka.main(Kafka.scala)
報錯原因:對應的Kafka代理已經啓動了。
解決辦法:查看一下server名稱並修改,命令行更改爲 .\bin\windows\kafka-server-start.bat .\config\new_server.properties
3、啓動Kafka報錯:
ERROR [KafkaServer id=2] Fatal error during KafkaServer startup. Prepare to shutdown (kafka.server.KafkaServer)
org.apache.kafka.common.KafkaException: Socket server failed to bind to 0.0.0.0:9093: Address already in use: bind.
報錯原因:兩個代理配置的端口號都是9093
解決辦法:把其中一個的端口號改成沒配置過的。
4、啓動Kafka報錯:ERROR [KafkaServer id=0] Fatal error during KafkaServer startup. Prepare to shutdown (kafka.server.KafkaServer)
org.apache.kafka.common.KafkaException: Failed to acquire lock on file .lock in D:\tmp\kafka-logs. A Kafka instance in another process or thread is using this directory.
報錯原因:兩個Kafka代理的日誌路徑是一樣的。
解決辦法:把其中一個server.properties文件中的日誌路徑修改成其他路徑。
5、用命令行刪除某個已創建的主題,發現該主題並沒有被刪除,只是做了個刪除標記,而且此時的Kafka會報錯,停止運行,即使重新啓動也會報同樣的錯誤,具體如下圖所示:
也看了一下其他人的解決方案,說是把Kafka的日誌(路徑是server.properties文件裏面log.dirs字段的值)和ZooKeeper的日誌(路徑是zoo.cfg文件裏面的dataDir字段的值)都刪掉,然後重新啓動。但是這麼做了之後發現問題還存在,明明日誌都刪了呀。
只好繼續查看,發現在Kafka的config目錄下有個“zookeeper.properties”文件,打開一看裏面也有個dataDir的字段,這裏填的是一個默認的路徑,與zoo.cfg文件裏面的dataDir字段的值不一致。難道是因爲這個dataDir不一致導致的?
我把“zoo.cfg”文件和“zookeeper.properties”文件中的dataDir都改成“D:/apache-zookeeper-3.5.7/data”,然後同樣地把已經產生的日誌刪掉,重新啓動ZooKeeper和Kafka,問題解決~
ps:好像只有windows環境會有這個問題,不過刪Topic還是要謹慎啊。