次のようなユースケースがあります。着信イベントごとに、特定のフィールドを調べて、ステータスがAからBに変更されたかどうかを確認し、変更された場合は、それを出力トピックに送信します。フローは次のようになります。キー「xyz」のイベントがステータスAで受信し、しばらくしてから別のイベントがキー「xyz」のステータスBで受信します。このコードは高レベルDSLを使用しています。
final KStream<String, DomainEvent> inputStream....
final KStream<String, DomainEvent> outputStream = inputStream
.map((k, v) -> new KeyValue<>(v.getId(), v))
.groupByKey(Serialized.with(Serdes.String(), jsonSerde))
.aggregate(DomainStatusMonitor::new,
(k, v, aggregate) -> {
aggregate.updateStatusMonitor(v);
return aggregate;
}, Materialized.with(Serdes.String(), jsonSerde))
.toStream()
.filter((k, v) -> v.isStatusChangedFromAtoB())
.map((k,v) -> new KeyValue<>(k, v.getDomainEvent()));
DSLを使用してこのロジックを書くためのより良い方法はありますか?
上記のコードの集計によって作成された状態ストアに関するいくつかの質問。
前もって感謝します!
デフォルトでは、永続的なRocksDBストアが使用されます。インメモリストアを使用する場合は、Materialized.as(Stores.inMemoryKeyValueStore(...))
を渡します。
一意のキーが無数にある場合、最終的にメインメモリまたはディスクが不足し、アプリケーションが停止します。セマンティクスに応じて、古いキーを期限切れにする代わりに、大きな「ギャップ」パラメータを使用してセッションウィンドウ集計を使用することで「TTL」を取得できます。
新しいデータの処理が行われる前に、状態は常に復元されます。インメモリストアを使用する場合、これは、基になる変更ログトピックを消費することによって発生します。州の規模によっては、これにはしばらく時間がかかる場合があります。永続的なRocksDBストアを使用する場合、状態はディスクから読み込まれるため、復元は不要であり、処理はすぐに実行されます。ローカルディスクの状態を失った場合にのみ、この場合、変更ログトピックからの復元が行われます。