カフカはどのようにしお珟実になったのか

カフカはどのようにしお珟実になったのか

おい、ハブル

私は独自の通知センタヌを開発しおいる Tinkoff チヌムで働いおいたす。 䞻に Spring Boot を䜿甚しお Java で開発し、プロゞェクト内で発生するさたざたな技術的問題を解決したす。

マむクロサヌビスのほずんどは、メッセヌゞ ブロヌカヌを通じお非同期に盞互通信したす。 以前は、IBM MQ をブロヌカヌずしお䜿甚しおいたしたが、負荷に察凊できなくなりたしたが、同時に高い配信保蚌がありたした。

代わりに、Apache Kafka が提䟛されたした。これは高い拡匵性を備えおいたすが、残念なこずに、さたざたなシナリオに合わせお構成するにはほが個別のアプロヌチが必芁です。 さらに、Kafka でデフォルトで機胜する少なくずも XNUMX 回の配信メカニズムでは、そのたたでは必芁なレベルの䞀貫性を維持できたせんでした。 次に、Kafka 構成に関する経隓を共有したす。特に、XNUMX 回限りの配信を構成しお䜿甚する方法に぀いお説明したす。

配達保蚌など

以䞋で説明する蚭定は、デフォルトの接続蚭定に䌎う倚くの問題を防ぐのに圹立ちたす。 ただし、最初に、デバッグを容易にする XNUMX ぀のパラメヌタに泚目したいず思いたす。

これは圹に立ちたす クラむアントID 生産者ず消費者にずっお。 䞀芋するず、アプリケヌション名を倀ずしお䜿甚でき、ほずんどの堎合、これで機胜したす。 ただし、アプリケヌションが耇数のコンシュヌマヌを䜿甚し、それらに同じ client.id を指定するず、次の譊告が衚瀺されたす。

org.apache.kafka.common.utils.AppInfoParser — Error registering AppInfo mbean javax.management.InstanceAlreadyExistsException: kafka.consumer:type=app-info,id=kafka.test-0

Kafka を䜿甚するアプリケヌションで JMX を䜿甚する堎合、これが問題になる可胜性がありたす。 この堎合、アプリケヌション名ずトピック名などを組み合わせお client.id 倀ずしお䜿甚するのが最善です。 構成の結果はコマンド出力で確認できたす。 kafka-消費者グルヌプ Confluent のナヌティリティから:

カフカはどのようにしお珟実になったのか

次に、メッセヌゞ配信を保蚌するシナリオを芋おみたしょう。 Kafka プロデュヌサヌにはパラメヌタヌがありたす ACKこれにより、クラスタヌ リヌダヌがメッセヌゞが正垞に曞き蟌たれたずみなすために必芁な確認応答の数を構成できたす。 このパラメヌタには次の倀を指定できたす。

  • 0 — 確認応答は考慮されたせん。
  • 1 はデフォルトのパラメヌタであり、確認応答に必芁なレプリカは 1 ぀だけです。
  • −1 — すべおの同期されたレプリカからの確認応答が必芁です (クラスタヌのセットアップ) min.insync.レプリカ).

リストされた倀から、acks が -1 に等しい堎合、メッセヌゞが倱われないずいう最も匷力な保蚌が䞎えられるこずは明らかです。

呚知のずおり、分散システムは信頌性が䜎いです。 䞀時的な障害から保護するために、Kafka プロデュヌサヌには次のオプションが甚意されおいたす。 再詊行、再送信詊行回数を蚭定できたす。 配信.タむムアりト.ms。 retries パラメヌタヌのデフォルト倀は Integer.MAX_VALUE (2147483647) であるため、メッセヌゞの再詊行回数はdelivery.timeout.ms のみを倉曎するこずで調敎できたす。

正確に XNUMX 回の配信を目指しお進んでいたす

リストされおいる蚭定により、プロデュヌサヌは高い保蚌でメッセヌゞを配信できたす。 ここで、メッセヌゞのコピヌが XNUMX ぀だけ Kafka トピックに曞き蟌たれるようにする方法に぀いお話したしょう。 最も単玔なケヌスでは、これを行うには、プロデュヌサヌにパラメヌタヌを蚭定する必芁がありたす。 冪等性を有効にする 本圓のこず。 冪等性により、XNUMX ぀のトピックの特定のパヌティションに XNUMX ぀のメッセヌゞだけが曞き蟌たれるこずが保蚌されたす。 冪等性を有効にするための前提条件は倀です。 acks = すべお、再詊行 > 0、接続ごずの最倧 in.flight.requests ≀ 5。 これらのパラメヌタが開発者によっお指定されおいない堎合、䞊蚘の倀が自動的に蚭定されたす。

冪等性が蚭定されおいる堎合は、同じメッセヌゞが毎回同じパヌティションに到達するようにする必芁がありたす。 これを行うには、partitioner.class キヌずパラメヌタヌをプロデュヌサヌに蚭定したす。 鍵から始めたしょう。 各提出物で同じである必芁がありたす。 これは、元の投皿のビゞネス ID を䜿甚するこずで簡単に実珟できたす。 Partitioner.classパラメヌタにはデフォルト倀がありたす- デフォルトパヌティショナ。 このパヌティショニング戊略では、デフォルトで次のように動䜜したす。

  • メッセヌゞの送信時にパヌティションが明瀺的に指定されおいる堎合は、それが䜿甚されたす。
  • パヌティションが指定されおいないが、キヌが指定されおいる堎合は、キヌのハッシュによっおパヌティションを遞択したす。
  • パヌティションずキヌが指定されおいない堎合は、パヌティションを XNUMX ぀ず぀遞択したす (ラりンドロビン)。

たた、キヌを䜿甚し、パラメヌタヌを䜿甚しお冪等で送信する 接続ごずの最倧フラむトリク゚スト数 = 1 Consumer でのメッセヌゞ凊理を合理化したす。 たた、クラスタヌにアクセス制埡が構成されおいる堎合は、トピックに冪等に曞き蟌む暩限が必芁になるこずにも泚意しおください。

突然、キヌによる冪等送信機胜がなくなったり、プロデュヌサヌ偎のロゞックで異なるパヌティション間でデヌタの䞀貫性を維持する必芁がある堎合には、トランザクションが圹に立ちたす。 さらに、チェヌン トランザクションを䜿甚するず、たずえば Kafka のレコヌドをデヌタベヌスのレコヌドず条件付きで同期できたす。 プロデュヌサぞのトランザクション送信を有効にするには、べき等であり、さらに蚭定する必芁がありたす。 トランザクションID。 Kafka クラスタヌにアクセス制埡が構成されおいる堎合、冪等レコヌドなどのトランザクション レコヌドには曞き蟌みアクセス蚱可が必芁になりたす。これは、transactional.id に栌玍されおいる倀を䜿甚しおマスクによっお付䞎できたす。

正匏には、アプリケヌション名などの任意の文字列をトランザクション識別子ずしお䜿甚できたす。 ただし、同じtransactional.idを䜿甚しお同じアプリケヌションの耇数のむンスタンスを起動するず、最初に起動したむンスタンスぱラヌで停止したす。これは、Kafkaがそれをゟンビプロセスず芋なすためです。

org.apache.kafka.common.errors.ProducerFencedException: Producer attempted an operation with an old epoch. Either there is a newer producer with the same transactionalId, or the producer's transaction has been expired by the broker.

この問題を解決するには、環境倉数から取埗したホスト名の圢匏でアプリケヌション名にサフィックスを远加したす。

プロデュヌサは構成されおいたすが、Kafka 䞊のトランザクションはメッセヌゞのスコヌプのみを制埡したす。 トランザクションのステヌタスに関係なく、メッセヌゞはすぐにトピックに移動したすが、远加のシステム属性がありたす。

このようなメッセヌゞがコンシュヌマによっお事前に読み取られるのを防ぐには、パラメヌタを蚭定する必芁がありたす。 分離レベル read_committed 倀に。 このようなコンシュヌマは、以前ず同様に非トランザクション メッセヌゞを読み取るこずができたすが、トランザクション メッセヌゞはコミット埌にのみ読み取るこずができたす。
前にリストしたすべおの蚭定を行っおいる堎合は、XNUMX 回限りの配信が構成されおいたす。 おめでずう

しかし、もう䞀぀ニュアンスがありたす。 䞊蚘で構成した Transactional.id は、実際にはトランザクションのプレフィックスです。 トランザクション マネヌゞャヌでは、シヌケンス番号が远加されたす。 受信した識別子は次のように発行されたす。 transactional.id.expiration.msこれは Kafka クラスタヌ䞊に構成されおおり、デフォルト倀は「7 日」です。 この間にアプリケヌションがメッセヌゞを受信しなかった堎合、次のトランザクション送信を詊行するず、次のメッセヌゞが送信されたす。 InvalidPidMappingException。 トランザクション コヌディネヌタヌは、次のトランザクションの新しいシヌケンス番号を発行したす。 ただし、InvalidPidMappingException が正しく凊理されない堎合、メッセヌゞが倱われる可胜性がありたす。

合蚈の代わりに

ご芧のずおり、単に Kafka にメッセヌゞを送信するだけでは十分ではありたせん。 パラメヌタの組み合わせを遞択し、すぐに倉曎できるように準備する必芁がありたす。 この蚘事では、XNUMX 回限りの配信蚭定を詳现に瀺し、遭遇した client.id およびtransactional.id 蚭定に関するいく぀かの問題に぀いお説明したした。 以䞋は、プロデュヌサヌずコンシュヌマヌの蚭定の抂芁です。

プロデュヌサヌ

  1. ACK = すべお
  2. 再詊行回数 > 0
  3. むネヌブル.冪等性 = true
  4. max.in.flight.requests.per.connection ≀ 5 (順序どおりに送信する堎合は 1)
  5. transactional.id = ${アプリケヌション名}-${ホスト名}

消費者

  1. isolation.level = read_committed

将来のアプリケヌションでの゚ラヌを最小限に抑えるために、リストされたパラメヌタの䞀郚の倀がすでに蚭定されおいるスプリング構成に察する独自のラッパヌを䜜成したした。

独習甚の教材をいく぀か玹介したす。

出所 habr.com

コメントを远加したす