Apache kafka 聚合到压缩主题,无限保留
我正在设置一个Kafka Streams应用程序,该应用程序使用某个主题(保留期:14天,清理时间:14天)。策略:删除,分区:1)。 我希望使用这些消息并将其输出到另一个主题(保留:-1,清理。策略:压缩,分区:3) 分组是按输入主题上的键进行的。 因此: 输入主题:Apache kafka 聚合到压缩主题,无限保留,apache-kafka,apache-kafka-streams,Apache Kafka,Apache Kafka Streams,我正在设置一个Kafka Streams应用程序,该应用程序使用某个主题(保留期:14天,清理时间:14天)。策略:删除,分区:1)。 我希望使用这些消息并将其输出到另一个主题(保留:-1,清理。策略:压缩,分区:3) 分组是按输入主题上的键进行的。 因此: 输入主题: Key: A Value: { SomeJson } Key: A Value: { Other Json} Key: B Value: { TestJson } 输出: Key: A Value: {[ {
Key: A Value: { SomeJson }
Key: A Value: { Other Json}
Key: B Value: { TestJson }
输出:
Key: A Value: {[ { SomeJson }, { Other Json } ]}
Key: B Value: {[ { TestJson } ]}
重要的是,输出主题上的内容永远不会丢失,因此它是ack:all和3个副本。
压缩主题中的每个键将有大约100条json记录。估计每个密钥的大小小于20kb
我还希望输出主题可以作为状态主题使用,这样就不必创建另一个主题来包含相同的信息
有人知道怎么做吗?我发现的大多数示例都与窗口相关:
当前代码:
val mapper = new ObjectMapper();
builder.stream(properties.getInputTopic(), Consumed.with(Serdes.String(), Serdes.String()))
.groupByKey()
.aggregate(
() -> new GroupedIdenthendelser(Collections.emptyList()),
(key, value, currentAggregate) -> {
val items = new ArrayList<>(currentAggregate.getIdenthendelser());
items.add(value);
return new GroupedIdenthendelser(items);
},
Materialized.with(Serdes.String(), new JsonSerde<>(GroupedIdenthendelser.class, mapper)))
.toStream()
.to(properties.getOutputTopic(), Produced.with(Serdes.String(), new JsonSerde<>(mapper)));
val mapper=new ObjectMapper();
stream(properties.getInputTopic(),consumered.with(Serdes.String(),Serdes.String()))
.groupByKey()
.合计(
()->新的GroupeDedentHendelser(Collections.emptyList()),
(键、值、currentAggregate)->{
val items=new ArrayList(currentAggregate.getIdenthendelser());
增加(价值);
返回新的GroupeDedentHendelser(项目);
},
with(Serdes.String(),新的JsonSerde(GroupedIdenthendelser.class,mapper)))
.toStream()
.to(properties.getOutputTopic(),producted.with(Serdes.String(),new-JsonSerde(mapper));
如果有人有一些其他提示,请告诉,因为这些数据是客户信息,所以如果有一些配置,我应该调整做告诉。或者,如果你知道一些博客文章/例子,我们将不胜感激
Edit:上面的代码示例似乎可行,但它创建了自己的状态主题,这是不需要的,因为输出主题始终包含相同的状态。因为输入主题有一个分区,所以每个应用程序只运行一个分区,并且它与固定大小的人(10000人给予或接受)相关,所以数据的大小也不会增加到每人20kb以上。每秒的事件数估计约为1/s,因此负载也不会太大
拓扑结构:
Sub-topology: 0
Source: KSTREAM-SOURCE-0000000000 (topics: [input-topic])
--> KSTREAM-AGGREGATE-0000000002
Processor: KSTREAM-AGGREGATE-0000000002 (stores: [KSTREAM-AGGREGATE-STATE-STORE-0000000001])
--> KTABLE-TOSTREAM-0000000003
<-- KSTREAM-SOURCE-0000000000
Processor: KTABLE-TOSTREAM-0000000003 (stores: [])
--> KSTREAM-SINK-0000000004
<-- KSTREAM-AGGREGATE-0000000002
Sink: KSTREAM-SINK-0000000004 (topic: output-topic)
<-- KTABLE-TOSTREAM-0000000003
子拓扑:0
来源:KSTREAM-Source-0000000000(主题:[输入主题])
-->KSTREAM-AGGREGATE-0000000002
处理器:KSTREAM-AGGREGATE-0000000002(存储:[KSTREAM-AGGREGATE-STATE-STORE-0000000001])
-->KTABLE-TOSTREAM-000000000 3
KSTREAM-SINK-000000000 4
看看您的示例数据集,我想您可能需要的是实时聚合。请看Confluent的博客文章作为起点。同意,但就我所见,大多数Kafka流要求输入主题分区和输出为1=1,因为在运行多个应用程序时,会在这两个分区上分配相同的分区。这在这里不是问题,我在查找代码示例时遇到问题。我在上面编辑了我的帖子,最后添加了一条评论。正如我发布的代码示例一样,它可以工作,但是它创建了一个状态主题,其中包含与输出主题相同的所有记录。我希望这是不必要的。佩奇可能会给你答案;请看一看这一节。正如您所理解的,这个例子是有效的。唯一的“问题”似乎是“重复”的话题?已经有一个票证允许此优化:--但目前不可能。您唯一能做的就是,不要添加to()
操作符,而直接从创建的变更日志主题中读取。