首页 > 解决方案 > Kafka Streams - 共享变更日志主题

问题描述

这是以下问题的后续问题:Kafka Streams - 如何扩展 Kafka 存储生成的更改日志主题

让我们假设流消费者需要在存储数据之前进行一些转换(通过 v->k 而不是 k->v 进行索引)。

最后,目标是每个消费者需要将完整的转换记录集 (v->k) 存储在 RocksDB 中。我知道上游的另一个处理器可以处理基于 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));

对于这种情况,这些选项中的哪一个是最佳实践或最优化(如果我的假设不成立,请让我正确)?

  1. 如果所有消费者都有不同的 applicationId,无论 groupId 是什么,他们都将消费所有 k-> 事件并生成多个包含所有内容的 changelog 中间主题(这不是最佳存储方式)。
  2. 如果所有消费者具有相同的 applicationId,但在不同的组中,因此独立加载所有 k->v 事件,他们将在共享变更日志流中贡献相同的计算 k->v 事件(基于 applicationId)。这看起来不是最优的,因为我们会多次计算和生成相同的数据。
  3. 如果所有消费者具有相同的 applicationId,并且在同一组中仅消费 k->v 事件的一部分(根据分区),他们将在共享变更日志流中贡献一部分计算的 k->v . 但我不清楚每个物化的 RocksDB 是否将拥有完整的数据集或只有流经其消费者管道的切片?

标签: apache-kafkaapache-kafka-streams

解决方案


对于 Kafka 流,applicationId == groupId. 因此(2)是不可能的。

对于 (3),该状态是分片/分区的,每个实例只有部分状态。

如果要获取状态的完整副本,则需要使用GlobalKTables而不是KTables.


推荐阅读