ロケーションイベント(key = user_id、value = user_location)を送信するKafkaトピックがあります。これを読み取り、KStream
として処理できます。
KStreamBuilder builder = new KStreamBuilder();
KStream<String, Location> locations = builder
.stream("location_topic")
.map((k, v) -> {
// some processing here, omitted form clarity
Location location = new Location(lat, lon);
return new KeyValue<>(k, location);
});
それはうまくいきますが、各ユーザーの最後の既知の位置を持つKTable
が欲しいです。どうすればいいですか?
中間トピックへの書き込みと読み取りを行うことができます:
// write to intermediate topic
locations.to(Serdes.String(), new LocationSerde(), "location_topic_aux");
// build KTable from intermediate topic
KTable<String, Location> table = builder.table("location_topic_aux", "store");
KTable
からKStream
を取得する簡単な方法はありますか?これはKafka= Streamsを使用した最初のアプリなので、おそらく明らかな何かを見逃しています。
現在のところ、これを行うための直接的な方法はありません。 Confluent FAQsで説明されているように、アプローチは完全に有効です。 http://docs.confluent.io/current/streams/faq.html#how-can-i-convert-a-kstream-to-a-ktable -without-an-aggregation-step
これは、コードに関して最も単純なアプローチです。ただし、(a)追加のトピックを管理する必要があり、(b)Kafkaとの間でデータが読み書きされるため、追加のネットワークトラフィックが発生するという欠点があります。
「ダミー削減」を使用する1つの代替方法があります。
KStreamBuilder builder = new KStreamBuilder();
KStream<String, Long> stream = ...; // some computation that creates the derived KStream
KTable<String, Long> table = stream.groupByKey().reduce(
new Reducer<Long>() {
@Override
public Long apply(Long aggValue, Long newValue) {
return newValue;
}
},
"dummy-aggregation-store");
このアプローチは、オプション1に比べてコードに関してやや複雑ですが、(a)トピックの手動管理が不要で、(b)Kafka is必要はありません。
全体として、自分で決める必要があります。
オプション2では、Kafka Streamsは、内部変更ログトピックを作成して、フォールトトレランスのためにKTableをバックアップします。したがって、両方のアプローチは、Kafka全体として、オプション2のやや複雑なコードとオプション1の手動トピック管理とのトレードオフです。