Kafkaは、グローバルストアを追加するためのユースケースをストリーミングします


8

kafkaストリームでトポロジを定義するときに、グローバルステートストアを追加できます。ソーストピックとが必要になりますProcessorSupplier。プロセッサーはレコードを受け取り、それらをストアに追加する前に理論的に変換できます。ただし、復元の場合、レコードはソーストピック(変更ログ)からグローバル状態ストアに直接挿入され、プロセッサで行われる最終的な変換はスキップされます。

   +-------------+             +-------------+              +---------------+
   |             |             |             |              |    global     |
   |source topic  ------------->  processor  +-------------->    state      |
   |(changelog)  |             |             |              |    store      |
   +-------------+             +-------------+              +---------------+
          |                                                         ^
          |                                                         |
          +---------------------------------------------------------+
              record directly inserted during restoration

StreamsBuilder#addGlobalStore(StoreBuilder storeBuilder、String topic、Consumed consumer、ProcessorSupplier stateUpdateSupplier)グローバルStateStoreをトポロジに追加します。

ドキュメントに従って

注:変換されたレコードをグローバルステートストア挿入するためにプロセッサを使用しないでください。このストアは、ソーストピックを変更ログとして使用し、復元時にソースから直接レコードを挿入します。このProcessorNodeは、StateStoreを最新の状態に保つために使用する必要があります。

並行して、主要なバグが現在カフカバグトラッカーで開かれています。ドキュメントに記載されている内容を正確に説明するトピックから状態を復元する場合、addGlobalStoreで提供されるKAFKA-7663カスタムプロセッサは使用されませんが、受け入れられたバグのようです。

KAFKA-7663が本当にバグかどうか疑問に思っています。ドキュメントによると、このように設計されているようです。その場合、ユースケースを理解するのに苦労します。
誰かがこの低レベルAPIの主な使用例を説明できますか?私が考えることができる唯一のことは、たとえばプロセッサでいくつかのログ操作を行うなどの副作用を処理することです。

おまけの質問:ソーストピックがグローバルストアの変更ログとして機能する場合、保存期間が切れたためにトピックからレコードが削除されると、グローバルステートストアから削除されますか?または、変更ログからストアを完全に復元した後にのみ、ストアで削除が行われますか?


2
古いドキュメントは問題を指摘しておらず、ドキュメントを「中間修正」として更新しただけであることに注意してください。
Matthias J. Sax

回答:


8

ええ、これはかなり奇妙な小さなキャッチ22ですが、ドキュメントは正しいです。グローバルステートストアのプロセッサは、レコードに対して何もしてはならず、それらをストアに永続化する必要があります。

私の知る限り、これは哲学的な問題ではなく、実際的な問題です。その理由は、単に観察する動作です... Streamsは、入力トピックをストアの変更ログトピックとして扱うため、復元中にプロセッサ(および逆シリアル化)をバイパスします。

状態の復元が処理をバイパスする理由は、通常、変更ログのデータはストア内のデータと同じであるため、新しいことを行うのは実際には間違っているためです。さらに、バイトをネットワークから取り出して状態ストアに一括書き込みするだけの方が効率的です。この場合、入力トピックは通常の変更ログトピックとは異なり、ストアの書き込み中に書き込みを受信しないため、「通常」と言います。

それだけの価値があるので、私もユースケースを理解するのに苦労しています。一見、次のいずれかを行う必要があります。

  1. そのプロセッサを完全に取り除き、復元と同じように、常にバイナリデータをネットワークからストアにダンプします。
  2. グローバルストアを再設計して、グローバルストアの前に任意の変換を許可します。次のいずれかを実行できます。
    • 入力トピックを引き続き使用し、復元中にプロセッサを逆シリアル化して呼び出す、または
    • 入力トピックをポーリングし、いくつかの変換を適用して、グローバルストア global-store-changelogに書き込むように、グローバルストアの実際の変更ログを追加します。次に、復元とレプリケーションに(入力ではなく)変更ログを使用できます。

ちなみに、後者の動作が必要な場合は、変換を適用しto(my-global-changelog)、「changelog」トピックを作成するために使用することで、今すぐそれを概算できます。次に、my-global-changelog入力の代わりに自分から読み取るグローバルストアを作成します。

したがって、あなたに直接的な答えを与えるために、KAFKA-7663はバグではありません。私はそれを機能要求に変えることを提案しているチケットにコメントします。

おまけの回答:ステートストアの変更ログとして機能するトピックには、保持を設定しないください。実際には、これは、圧縮を有効にして無限の成長を防ぎ、ログの保持を無効にする必要があることを意味します。

実際には、古いデータが保持されなくなり、ドロップされることは「イベント」ではなく、コンシューマはそれが発生したかどうか、いつ発生したかを知る方法がありません。したがって、この非イベントに応答して状態ストアからデータを削除することはできません。あなたが説明するようにそれは起こります...レコードはいつまでもグローバルストアの中にあるだけです。インスタンスが置き換えられると、新しいインスタンスは入力から復元され、(明らかに)その時点でトピックに存在するレコードのみを受け取ります。したがって、Streamsクラスターは全体として、グローバルな状態の一貫性のないビューで終了します。そのため、保持を無効にする必要があります。

ストアから古いデータを「ドロップ」する正しい方法は、目的のキーのトゥームストーンを入力トピックに書き込むことです。これは、クラスターのすべてのメンバーに正しく伝搬され、復元中に正しく適用され、ブローカーによって正しく圧縮されます。

これがすべて役に立てば幸いです。間違いなく、チケットにチャイムを入れて、APIがより直感的になるように形作ってください!


うん、それは決定的に多くを助けます。この詳細な回答に感謝します:)
ズーム

2
「ステートストアの変更ログとして機能するトピックには保持を設定しないでください。」を明確にするために、一定の時間が経過した後、または一定のサイズのしきい値を超えた後にデータを期限切れにするようにトピックを設定しないでください。代わりに、トピック内でデータを「永久に」保持する必要があります。圧縮を有効にすると、トピックが境界を超えて大きくならないようにすることができます。
マイケルG.ノール

説明を探していました。
どうも
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.