Apache Kafka docsKStream-to-KStream Joins are always windowed joins
に基づいて、私の質問は、ウィンドウのサイズをどのように制御できますか?データを保持するための同じサイズですか?トピックですか?または、たとえば、データを1か月間保持しても、過去1週間だけストリームに参加できますか?
ウィンドウ化されたKStreamからkStreamへのウィンドウ化された結合を示す良い例はありますか?
私の場合、2つのKStream、kstream1
とkstream2
があります。10日間のkstream1
から30日間のkstream2
に参加できるようにしたいとします。
それは絶対に可能です。 Stream演算子を定義するときは、結合ウィンドウのサイズを明示的に指定します。
KStream stream1 = ...;
KStream stream2 = ...;
long joinWindowSizeMs = 5L * 60L * 1000L; // 5 minutes
long windowRetentionTimeMs = 30L * 24L * 60L * 60L * 1000L; // 30 days
stream1.leftJoin(stream2,
... // add ValueJoiner
JoinWindows.of(joinWindowSizeMs)
);
// or if you want to use retention time
stream1.leftJoin(stream2,
... // add ValueJoiner
(JoinWindows)JoinWindows.of(joinWindowSizeMs)
.until(windowRetentionTimeMs)
);
詳細については、 http://docs.confluent.io/current/streams/developer-guide.html#joining-streams を参照してください。
スライディングウィンドウは、基本的に追加の結合述語を定義します。 SQLのような構文では、これは次のようになります。
SELECT * FROM stream1, stream2
WHERE
stream1.key = stream2.key
AND
stream1.ts - before <= stream2.ts
AND
stream2.ts <= stream1.ts + after
どこ before == after == joinWindowSizeMs
この例では。 JoinWindows#before()
とJoinWindows#after()
を使用してこれらの値を明示的に設定する場合、before
とafter
も異なる値を持つことができます。
ソーストピックの保持時間は、Kafka Streams自体によって作成された変更ログトピックに適用される指定されたwindowRetentionTimeMs
とは完全に独立しています。ウィンドウの保持により、順序が正しくないレコードを相互に結合できますつまり、遅れて到着したレコード(Kafkaにはオフセットベースの注文保証がありますが、 タイムスタンプに関しては、レコードの順序が狂っている可能性があります)。
Matthias J. Saxが言ったことに加えて、次の場所にストリーム間(ウィンドウ)結合の例があります: https://github.com/confluentinc/examples/blob/3.1.x/kafka-streams /src/test/Java/io/confluent/examples/streams/StreamToStreamJoinIntegrationTest.Java
これは、Apache Kafka 0.10.1、つまり2017年1月現在の最新バージョンを使用するConfluent 3.1.x用です。使用するコード例については、上記のリポジトリのmaster
ブランチを参照してください。新しいバージョン。
上記のコード例の重要な部分は次のとおりです(ここでも、Kafka 0.10.1)の場合、質問に少し適合しています。この例は、OUTERJOINを示していることに注意してください。
long joinWindowSizeMs = TimeUnit.MINUTES.toMillis(5);
long windowRetentionTimeMs = TimeUnit.DAYS.toMillis(30);
final Serde<String> stringSerde = Serdes.String();
KStreamBuilder builder = new KStreamBuilder();
KStream<String, String> alerts = builder.stream(stringSerde, stringSerde, "adImpressionsTopic");
KStream<String, String> incidents = builder.stream(stringSerde, stringSerde, "adClicksTopic");
KStream<String, String> impressionsAndClicks = alerts.outerJoin(incidents,
(impressionValue, clickValue) -> impressionValue + "/" + clickValue,
// KStream-KStream joins are always windowed joins, hence we must provide a join window.
JoinWindows.of(joinWindowSizeMs).until(windowRetentionTimeMs),
stringSerde, stringSerde, stringSerde);
// Write the results to the output topic.
impressionsAndClicks.to(stringSerde, stringSerde, "outputTopic");