这是一个后续问题:Kafka Streams - How to scale Kafka store generated changelog topics
让我们假设流消费者需要在存储数据之前进行一些转换(通过v-> k而不是k-> v进行索引) .
最后,目标是每个消费者需要在rocksDB中存储完整的转换记录集(v-> k) . 我理解上游的另一个处理器可以负责根据k-> v生成v-> k,最终消费者可以简单地从全局表中实现新主题 . 但如果管道全部在最终消费者处完成会发生什么?
KTable<Key, Value> table = builder.table(topic);
table.groupBy((k, v) -> KeyValue.pair(v, k)).reduce((newValue, aggValue) -> newValue,
(newValue, aggValue) -> null,
Materialized.as(STORE_NAME));
对于这种情况,哪种选择是最佳做法或最佳选择(如果我的假设已经取消,请帮我正确)?
-
如果所有消费者具有不同的applicationId,则无论groupId如何,他们都将消耗所有k->事件并生成具有所有内容的多个changelog中间主题(这不是最佳存储方式) .
-
如果所有消费者具有相同的applicationId,但是在不同的组中,因此独立加载所有k-> v事件,他们将在共享的更改日志流中贡献相同的计算k-> v事件(基于applicationId) . 这看起来不是最佳的,因为我们会多次计算和生成相同的数据 .
-
如果所有消费者具有相同的applicationId,并且在同一组中仅消耗k-> v事件的一部分(根据分区),则他们将在共享更改日志中贡献计算的k-> v的一部分流 . 但我不清楚每个物化的rocksDB是否会拥有完整的数据集或只有流经其消费者管道的切片?
1 回答
对于Kafka Streams,
applicationId == groupId
. 因此(2)是不可能的 .对于(3),该状态是分片/分区的,并且每个实例仅具有部分状态 .
如果要获取状态的完整副本,则需要使用
GlobalKTables
而不是KTables
.