結果の集計に各キーのすべての値が含まれるようにするにはどうすればよいですか? IE 各ワーカーインスタンスに値のサブセットを持たせたくありません。
一般に、Kafka Streams は、同じキーのすべての値が同じ (そして 1 つだけの) ストリーム タスクによって処理されることを保証します。これは、1 つのアプリケーション インスタンス (「ワーカー インスタンス」と説明したもの) のみがその値を処理することも意味します。鍵。アプリ インスタンスは 1 つ以上のストリーム タスクを実行できますが、これらのタスクは分離されていることに注意してください。
この動作はデータのパーティショニングによって実現され、Kafka Streams はパーティションが常に同じ 1 つのストリーム タスクのみによって処理されるようにします。キー/値への論理的なリンクは、Kafka と Kafka Streams では、キーが常に同じパーティションに送信されることです (ここに落とし穴がありますが、この質問)、したがって、1 つの特定のパーティション (考えられる多くのパーティションの中で) には、同じキーのすべての値が含まれています。
A
2 つのストリームと を結合する場合など、状況によってはB
、両方のストリームからのデータが同じストリーム タスク内に同じ場所にあることを確認するために、集約が同じキーで動作することを確認する必要があります。関連する入力ストリーム パーティションと一致するキー (それぞれ fromA
とB
) が同じストリーム タスクで利用できるようにします。ここで使用する典型的な方法はselectKey()
. それが完了すると、Kafka Streams は、2 つのストリーム A と B を結合するため、および結合された出力ストリームを作成するために、同じキーのすべての値が同じストリーム タスクによって処理され、したがって同じアプリケーション インスタンスによって処理されることを保証します。
例:
- ストリームには値
A
を持つキーがあります。userId
{ georegion }
- ストリームには値
B
を持つキーがあります。georegion
{ continent, description }
2 つのストリームの結合は、両方のストリームが同じキーを使用する場合にのみ機能します (Kafka 0.10.0 以降)。A
この例では、これは、結果のキーが からuserId
に変更されるように、ストリームを再キー化 (したがって再パーティション化) する必要があることを意味しますgeoregion
。そうしないと、Kafka 0.10 以降、実際に結合を実行する責任があるストリーム タスクにデータが同じ場所に配置されていないためA
、結合できません。B
この例では、次の方法でストリームを再キー/再パーティション化できますA
。
// Kafka 0.10.0.x (latest stable release as of Sep 2016)
A.map((userId, georegion) -> KeyValue.pair(georegion, userId)).through("rekeyed-topic")
// Upcoming versions of Kafka (not released yet)
A.map((userId, georegion) -> KeyValue.pair(georegion, userId))
このthrough()
呼び出しは、実際に再パーティション化をトリガーするために Kafka 0.10.0 でのみ必要であり、Kafka の以降のバージョンではこれらが自動的に行われます (この今後の機能は既に完了しており、Kafka で利用可能ですtrunk
)。
これは StateStore が使用されるものですか? Kafka はこれを独自に管理しますか、それとも方法を考え出す必要がありますか?
一般的に、いいえ。上記の動作は、状態ストアではなく、パーティショニングによって実現されます。
ストリームに対して定義した操作のためにステート ストアが関係する場合があります。たとえば、ウィンドウ操作では状態を管理する必要があるため、バックグラウンドで状態ストアが作成されます。しかし、実際の質問 - 「結果の集計に各キーのすべての値が含まれることを保証する」 - は状態ストアとは関係なく、パーティション化の動作に関するものです。