この記事ではTopicの __consumer_offsets
のキーとなるtopicName, partitionNumber, groupIdについて調査し紹介します。
背景
以下の記事にて、Debeziumの運用時に気にするポイントについて説明しました。
その際に、KafkaのTopicという概念が出てきました。
Kafkaでは __consumer_offsets
というようなトピックを持っていて、各Subscriberがどこまでのメッセージを消費したのかのオフセットを持っているとのことでした。
この__consumer_offsets
は [topicName, partitionNumber, groupId] のキーで同様のSubscriberかどうかを判定しているようです。
- https://stackoverflow.com/questions/56947184/how-does-consumer-offsets-keep-offset-for-two-consumers
- https://medium.com/@felipedutratine/kafka-consumer-offsets-topic-3d5483cda4a6
さて、ここで疑問が湧きます。
キーとなっている [topicName, partitionNumber, groupId]って具体的に何なんだろうか。
今回はこれについて調べ、イメージ図を作成します。
対象者
- Topicの概念イメージの解像度を少しだけ高めたい
イメージ
私の調査以前のKafkaのTopicに対する解像度は以下の通り。
「TopicにはProducerから送信されたMessageが保持されている」程度の理解です。
topicNameとpartitionNumber
これは、Topicの解像度を少しだけ高くするとpartitionNumberが何なのかが見えてきます。
Topicの1つを掘り下げてみると以下のようなイメージです。
以下の記事中での説明がとても分かりやすかったです。
https://qiita.com/sigmalist/items/5a26ab519cbdf1e07af3
- 1つのTopic > 複数のPartitionで構成
- 各Kafka ServerにBrokerが存在し、各PartitionはBroker間で複製されたReplicaで構成
- ※ 耐障害性を高めるためにKafkaをCluster構成にした前提
つまり、Producer(例えばDebezium)から送られたMessageはKafkaの該当Topic内の各Partitionに保持されます。
もう少し細かく言うと、Messageは各Partitionの Leader replica
のBroker上
に保持された後に、その他の Follower replica
のBroker上にReplicateされます。
各Consumerは特定のPartitionをウォッチして、新しいMessageをTopicから取得します。
ここまでで、__consumer_offsets
のキーとなっているtopicNameとpartitionNumberのイメージは少し湧いたかと思います。
groupId
残りは groupId
とは何なのかです。
これは Consumer group
の事を指しています。
Consumer側は1つ以上のConsumerから成るConsumer Groupを構成出来ます。
1つのConsumerが1のPartitionのみからMessageを読み込むよりも、Messageの読み込みを各Partitionに分散させたほうが、より効率的で早いよね的なイメージです。
また、Consumerも1つだけではなく、複数のConsumerが複数のPartitionからMessageを並列で読み込む事ができます。
更に、同一のConsumer Group内で重複したMessageの読み込みも基本的には発生しないようになっているようです。
例えば、TopicのPartitionが3つ、Consumerが2つのConsumer Groupが構成されている場合のイメージは以下の通りです。
※ ラウンドロビンでTopicのメッセージが処理される場合
Topic内のメッセージが分散的に読み込まれ、Consumer側でも分散して処理されることで、より効率的にメッセージがConsumeされます。
※ Partition側に対してラウンドロビンなのか、Consumerに対してラウンドロビンなのかは裏取りして確証を持っている訳では無く、私の理解が間違っていたらごめんなさい…
なお、具体的な検証内容も含めて、以下の記事がとても参考になりました。
https://pppurple.hatenablog.com/entry/2018/11/20/213651
こちらもまたまたお世話になりました。
https://qiita.com/sigmalist/items/3b512e2ab49b07271665#consumer-group%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6
ここまでで、__consumer_offsets
の各キーのイメージが少し湧いたかと思います。
__consumer_offsets
のキー
これで、以下の問いに対する解像度が少しは高くなりました。
キーとなっている[topicName, partitionNumber, groupId]って具体的に何なんだろうか。
どの Consumer Group
が何の Topic
の どの Partition
を読んでいるのかがキーとなっているわけですね。
まとめ
今回は、Topicの解像度を高めるために頭の中を整理して、イメージ図に起こしてみました。
今回は色んな記事を漁りつつ、論理的なイメージを整理しただけの話でした。
なので、この記事の信頼性は高く無いです(話半分で見ていただけると幸いです)。
次は具体的に検証して確かめられればと思います。
ここまで見ていただき、ありがとうございました。
参考資料
本記事執筆にあたって、色んなドキュメントや記事を参考にさせていただきました(正直、私の記事よりも解像度が高いです…)。