6
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

始めに

前回に引き続きApache Kafkaについて勉強したことをまとめてみました。

おさらいとして、前回の記事に書いた内容も含んではいますが、基礎的な知識に関しては以下の記事を読んでいただくようお願いします。

今回は特に、「Kakfaをよりうまく使いこなすために」という観点で、いくつかの知識をピックアップして紹介していきたいと思います。

この記事の対象者

・Apache Kafkaの勉強を始めた方
・Apache Kakfaに関する基礎的な知識を得たい方

この記事で伝えること

・Apache Kafkaを支える仕組み
・Apache Kafkaを使いこなすために必要な知識

データのロストと処理継続性のトレードオフ

おさらい〜Replicaについて〜

Kafkaでは、異なるBrokerに同一TopicのPartitionを分散して配置します。
その中で一つのPartitionがReader Replicaとして実際にProducer・Consumerとやりとりをします。他のPartitionはFollower ReplicaとしてLeader Replicaからメッセージを取得して複製を保ち、障害発生時に備えています。

分散処理1.png

レプリカの同期状態

Leader Replicaの複製を保っているFollower Replicaは In-Sync Replica (ISR) と呼ばれます。
逆に、Leader Replicaの複製状態になっていないFollower Replicaを Under Replicated Partions と呼びます。

各Topicでは、 最小ISR数(min.insync.replica) (= 複製状態を保つべきレプリカの最小数)の設定が可能です。

これにより、Leader ReplicaからFollower Replicaへの複製に遅延や停止が発生しても、これを許容し 最低限の複製を保っていればProducer・Consumerとのやりとりを続けることが可能 です。
あるPartitionのISR数が最小数を下回ると、そのPartitionのLeader ReplicaはProducerから書き込み出来なくなります。

(例)Replica数が3・min.insync.replicaが2
 → 最低2つのReplicaが複製を保っていればやりとりを継続する

kafka_1.png

Messageの到達保証レベル

おさらい〜Ackについて〜

Brokerがメッセージを受け取った際に、Producerに対して受け取ったことを返答するAckを送信します。ProducerがAckを受け取らなかった場合、Producerはメッセージを再送するべきだと判断することができます。

kafka_2.png

BrokerがどのタイミングでAckを送信するかについて、以下3種類の到達保証レベルを設定することができます。

設定 説明
0 Producerは Ackを待たずに 次のメッセージを送信する
1 Leader Replicaへの書き込みが完了したらAckを返す
all 最小ISR数まで書き込みが完了したら Ackを返す

0に設定した場合、何らかの障害でメッセージの書き込みが失敗しても、Producerはメッセージの送信を続けることができます。

一方でallに設定した場合、複製状態のレプリカができて初めて受取済となるため、 データをロストする可能性が低く なります。
しかし、最小ISR数の設定によっては一つのBrokerが故障した場合、 メッセージの送信が止まってしまう 可能性があります。

ここからは最小ISR数とAck設定の関係性についてみていきましょう。

最小ISR数とAck設定の関係性

Ack設定をallにした場合、最小ISR数の設定によってメッセージの書き込みを継続できるかどうかが決まります。
以下2つのケースを比較していきましょう。

  • ケース1:最小ISR数がレプリカ数と同じである場合
    Brokerが一台故障した場合、該当のレプリカが障害解消後にISRとなるまで 書き込みができなくなる

kafka_3.png

  • ケース2:最小ISR数がレプリカ数よりも少ない場合
    Brokerが一台故障した場合でも、ISR数が2であればAckを返すため、 書き込みを継続できる

kafka_4.png

処理を継続できるという点においては、ケース1よりもケース2の方が優れています。
その一方で、ケース2において故障したBrokerの復旧前にさらに別のBrokerで障害が発生した場合、 処理中のメッセージをロストするリスクが高く なります。

このように、最小ISRの設定とAckの設定は、

  • データをロストしないこと
  • 処理を継続すること
    トレードオフを調整する 役割を担っていると言えます。

よってケース1とケース2のどちらかが優れているというわけではなく、システムの要件やKafkaの利用目的によって設定を決めるべきだということになります。

Offset Commitのタイミング

おさらい〜Offset Commitについて〜

ConsumerがBrokerに対してどのメッセージまで処理が完了したかという記録を残すことをOffset Commitといいます。
この情報により、障害復旧後Brokerからのメッセージ受信を再開する際、Consumerはどのメッセージから処理を再開すれば良いかを判断することができます。

kafka_5.png

Offset Commitには以下二つの方法があります。
それぞれの特徴とメリット・デメリットをみていきましょう。

  • Auto Offset Commit
  • Manual Offset Commit

Auto Offset Commit

Autoとあるように、 一定の間隔ごとに自動で Offset Commitを行う方式のことです。
Offset Commitを行う間隔はオプションで指定することができ、デフォルトでは5秒となっています。

kafka_6.png

メリット

Consumer側でOffset Commitを明示的に行う必要がないため、Consumer側の処理が簡潔になります。

デメリット

Consumer側で障害が発生した際、メッセージが失われたり、メッセージの重複(同じメッセージを再度処理する)が発生したりする可能性があります。

  • メッセージのロストが発生するケース
    Offset Commitされたメッセージの処理が完了する前に障害が発生した場合、処理中のメッセージまで「処理が完了した」と記録されてしまいます。そのため障害解消後、処理途中であったメッセージは処理されなくなってしまいます。

kafka_7.png

  • メッセージの重複が発生するケース
    複数のメッセージの処理が完了しているものの、Offset Commitが行われる前に障害が発生した場合、処理が完了しているはずのメッセージも「処理が完了していない」と記録されてしまいます。そのため障害解消後、複数のメッセージを再度処理することになってしまいます。

kafka_8.png

Manual Offset Commit

Consumer側にOffset Commitの処理を記述し、明示的にOffset Commitを行う方式のことです。つまり、任意のタイミングでOffset Commitを行うことができます。

kafka_9.png

メリット

適切に利用することで、メッセージのロストを発生させない ようにできます。
各メッセージを取得し処理が完了したタイミングでOffset Commitを行うようにすれば、Offset Commitされたメッセージは 必ず処理が完了している ことになるため、データのロストを防ぐことができます。
また、メッセージの重複も完全に防ぐことはできませんが、重複するメッセージの数は減らすことができます。

kafka_10.png

デメリット

一般的にはAuto Offset Commitの方が頻繁にOffset Commtiを行うことになるため、Brokerへの負荷が高くなります。
また、仕組みを理解して正しく使用する必要があるため、初期コスト・維持コストはAuto Offset Commitに比べて高くなります。

このように、Offset Commitを行うタイミングを適切に設定することによって、 メッセージの重複が発生する可能性はありつつも、データのロストは防ぐ ことができます。

ただしOffset Commitの頻度によってはスループットに大きく影響を与えることになるため、Auto Offset CommitとManula Offset Commitどちらか利用するかは要件によって判断する必要があります。

まとめ

  • データロストの可能性を下げることと処理の継続性を担保することはトレードオフの関係にある。そのため、最小ISR数とAck設定によって、適切に調整する必要がある。

  • Offset Commitを行うタイミングはAuto / Manualで設定することができる。適切にOffset Commitのタイミングを設定することで、Consumer側のデータのロストを完全に防ぐ仕組みを作ることができる。

最後に

今回はどうすればKafkaをより使いこなせるか?という観点で、学んだことをまとめてみました。
Kafkaの利用において、ベストプラクティスはなく、システムの要件によって設定等を考えていく必要があるというところが印象的でした。

今度こそはKafkaを使ったアプリケーションの開発にも取り組んでみようと思います。

参考文献

6
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?