Kafka 如何讀取offset topic內容 (__consumer_offsets)

Kafka 如何讀取offset topic內容 (__consumer_offsets)

  衆所周知,由於Zookeeper並不適合大批量的頻繁寫入操作,新版Kafka已推薦將consumer的位移信息保存在Kafka內部的topic中,即__consumer_offsets topic,並且默認提供了kafka_consumer_groups.sh腳本供用戶查看consumer信息。

  不過依然有很多用戶希望瞭解__consumer_offsets topic內部到底保存了什麼信息,特別是想查詢某些consumer group的位移是如何在該topic中保存的。針對這些問題,本文將結合一個實例探討如何使用kafka-simple-consumer-shell腳本來查詢該內部topic。

1. 創建topic “test”

bin/kafka-topics.sh --zookeeper localhost:2181 --create --topic test --replication-factor 3 --partitions 3

2. 使用kafka-console-producer.sh腳本生產消息

  由於默認沒有指定key,所以根據round-robin方式,消息分佈到不同的分區上。 (本例中生產了64條消息)

3. 驗證消息生產成功

bin/kafka-run-class.sh kafka.tools.GetOffsetShell --broker-list localhost:9092,localhost:9093,localhost:9094 --topic test --time -1

結果輸出表明64條消息全部生產成功!

test:2:21

test:1:21

test:0:22

4. 創建一個console consumer group

bin/kafka-console-consumer.sh --bootstrap-server localhost:9092,localhost:9093,localhost:9094 --topic test --from-beginning --new-consumer

5. 獲取該consumer group的group id(後面需要根據該id查詢它的位移信息)

bin/kafka-consumer-groups.sh --bootstrap-server localhost:9092,localhost:9093,localhost:9094 --list --new-consumer

輸出: console-consumer-46965  (記住這個id!)

6. 查詢__consumer_offsets topic所有內容

注意:運行下面命令前先要在consumer.properties中設置exclude.internal.topics=false

0.11.0.0之前版本

bin/kafka-console-consumer.sh --topic __consumer_offsets --zookeeper localhost:2181 --formatter "kafka.coordinator.GroupMetadataManager\$OffsetsMessageFormatter" --consumer.config config/consumer.properties --from-beginning

0.11.0.0之後版本(含)

bin/kafka-console-consumer.sh --topic __consumer_offsets --zookeeper localhost:2181 --formatter "kafka.coordinator.group.GroupMetadataManager\$OffsetsMessageFormatter" --consumer.config config/consumer.properties --from-beginning

 

默認情況下__consumer_offsets有50個分區,如果你的系統中consumer group也很多的話,那麼這個命令的輸出結果會很多。

7. 計算指定consumer group在__consumer_offsets topic中分區信息

這時候就用到了第5步獲取的group.id(本例中是console-consumer-46965)。Kafka會使用下面公式計算該group位移保存在__consumer_offsets的哪個分區上:

Math.abs(groupID.hashCode()) % numPartitions

所以在本例中,對應的分區=Math.abs("console-consumer-46965".hashCode()) % 50 = 11,即__consumer_offsets的分區11保存了這個consumer group的位移信息,下面讓我們驗證一下。

8. 獲取指定consumer group的位移信息 

0.11.0.0版本之前

bin/kafka-simple-consumer-shell.sh --topic __consumer_offsets --partition 11 --broker-list localhost:9092,localhost:9093,localhost:9094 --formatter "kafka.coordinator.GroupMetadataManager\$OffsetsMessageFormatter"

0.11.0.0版本以後(含)

bin/kafka-simple-consumer-shell.sh --topic __consumer_offsets --partition 11 --broker-list localhost:9092,localhost:9093,localhost:9094 --formatter "kafka.coordinator.group.GroupMetadataManager\$OffsetsMessageFormatter"

下面是輸出結果:

複製代碼
...
[console-consumer-46965,test,2]::[OffsetMetadata[21,NO_METADATA],CommitTime 1479092279434,ExpirationTime 1479178679434]
[console-consumer-46965,test,1]::[OffsetMetadata[21,NO_METADATA],CommitTime 1479092284246,ExpirationTime 1479178684246]
[console-consumer-46965,test,0]::[OffsetMetadata[22,NO_METADATA],CommitTime 1479092284246,ExpirationTime 1479178684246]
[console-consumer-46965,test,2]::[OffsetMetadata[21,NO_METADATA],CommitTime 1479092284246,ExpirationTime 1479178684246]
[console-consumer-46965,test,1]::[OffsetMetadata[21,NO_METADATA],CommitTime 1479092284436,ExpirationTime 1479178684436]
[console-consumer-46965,test,0]::[OffsetMetadata[22,NO_METADATA],CommitTime 1479092284436,ExpirationTime 1479178684436]
[console-consumer-46965,test,2]::[OffsetMetadata[21,NO_METADATA],CommitTime 1479092284436,ExpirationTime 1479178684436]
 ...
複製代碼

  上圖可見,該consumer group果然保存在分區11上,且位移信息都是對的(這裏的位移信息是已消費的位移,嚴格來說不是第3步中的位移。由於我的consumer已經消費完了所有的消息,所以這裏的位移與第3步中的位移相同)。另外,可以看到__consumer_offsets topic的每一日誌項的格式都是:[Group, Topic, Partition]::[OffsetMetadata[Offset, Metadata], CommitTime, ExpirationTime]

 

  okay,寫到此你應該已經知道如何查詢__consumer_offsets topic的內容了吧。希望本文對你有所幫助。(Kafka當然還提供了Java APIs用於查詢,具體使用方法不在這裏贅述了,有興趣的可以看這裏。)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章