kafka-streams会话窗口保留期

时间:2018-04-17 12:11:32

标签: apache-kafka-streams

我在会话窗口上为我的一个流要求做POC。为此,我使用会话窗口,因为这符合要求,我必须将具有唯一事务ID的事件聚合到列表中。每个事务可以有不同应用程序生成的多个事件,并将它们推送到kafka。以下是代码

    StreamsConfig streamsConfig = new StreamsConfig(getProperties());
    Serde<String> stringSerde = Serdes.String();
    Serde<Transaction> transactionSerde = StreamsSerdes.TransactionSerde();

    Aggregator<String,Transaction, List<Transaction>> agg = (key, value, list)
            -> {
        list.add(value);
        return list;
    };

    Merger<String, List<Transaction>> merger = (key, v1, v2) ->
       Stream.concat(v1.stream(), v2.stream())
               .collect(Collectors.toList());

    Materialized<String,List<Transaction>,SessionStore<Bytes, byte[]>>
            materialized = Materialized.<String,List<Transaction>>as(Stores
            .persistentSessionStore
            ("trans-store", 1000 * 30)).withKeySerde(stringSerde).withValueSerde(StreamsSerdes
            .TransactionsListSerde());


    Initializer<List<Transaction>> init = () -> new ArrayList<>();

    StreamsBuilder builder = new StreamsBuilder();
    KTable<Windowed<String>, List<Transaction>> customerTransactionCounts =
             builder.stream(TRANSACTIONS_TOPIC, Consumed.with(stringSerde, transactionSerde).withOffsetResetPolicy(LATEST))
            .groupBy((noKey, transaction) -> transaction.getCustomerId(),
                    Serialized.with(stringSerde, transactionSerde))
            .windowedBy(SessionWindows.with(10000).until(1000 * 30))
                     .aggregate(init,agg,merger,materialized);


    customerTransactionCounts.toStream().print(Printed.<Windowed<String>, List<Transaction>>toSysOut()
            .withLabel("Customer Transactions List").withKeyValueMapper((key, list) ->
                    ("Current Time " + new Date().toString() + " Customer Id - " + key.key()  +
                    " START " +
                    new Date
                    (key.window().start()).toString() + " --- END " + new Date(key.window().end()).toString()+ "  " + list)));


    KafkaStreams kafkaStreams = new KafkaStreams(builder.build(), streamsConfig);
    kafkaStreams.cleanUp();

保留期如何在这里工作?

1)首先,我使用事务日期范围

来获取一些事务ID为X的数据

START 4月16日22:25:40 EDT 2018 --- END Mon Apr 16 22:25:49 EDT 2018

所有这些都是在进入同一会话时汇总的。

2)接下来i摄取单一记录交易ID X时间 START 1月16日22:26:45 EDT 2018。

我按预期在提交间隔后看到1条记录

根据我的理解,流时间变为 22:26:45 。此时,上述摄取的记录应该从州商店到期,作为结束时间&lt;流时间 - 保留期(30秒)

3)接下来i摄取记录单记录事务ID X,其与第一组事件处于相同的时间范围内。我在提交间隔后看到第一步中的所有记录和聚合结果中的新当前记录。

第一组记录不应该从州商店过期,因为它们已超过保留期???

在第三步中,我假设我只获得一个聚合记录,因为较旧的记录应该被删除。保留期何时会从州商店中删除记录?

1 个答案:

答案 0 :(得分:1)

保留时间是“最小” - 为了更有效地过期,数据存储在所谓的段中(基于时间间隔),并且当段中的所有数据都超过保留时间时段将过期。