HazelcastJet滚动聚合,其中删除了先前的数据并添加了新数据

时间:2019-01-30 12:37:50

标签: hazelcast-jet

我们有一个用例,其中我们正在接收来自kafka的消息,需要对其进行汇总。必须采用以下方式进行汇总:如果更新的ID相同,则需要减去现有值并添加新值。

从各种论坛上,我了解到jet不会存储原始值,而是存储汇总结果和一些内部数据。

在这种情况下,我该如何实现?

示例

Balance 1 {id:1, amount:100} // aggregated result 100
Balance 2 {id:2, amount:200} // 300
Balance 3 {id:1, amount:400} // 600 after removing 100 and adding 400

我可以实现每次添加的简单用法。但是我无法实现需要减去现有值并必须添加新值的汇总。

rollingAggregation(AggregatorOperations.summingDouble(<login to add remove>))
    .drainTo(Sinks.logger()).
  1. 余额1,2,3是消息的顺序
  2. 注释显示jet每次发送的消息的合计值。
  3. 我的目的是添加新金额(如果id首次出现),并且如果更新后的余额为i,则减去金额。 e。 ID与之前相同。

1 个答案:

答案 0 :(得分:1)

您可以尝试执行自定义聚合操作,该操作将发出以前和当前看到的值,如下所示:

public static <T> AggregateOperation1<T, ?, Tuple2<T, T>> previousAndCurrent() {
    return AggregateOperation
            .withCreate(() -> new Object[2])
            .<T>andAccumulate((acc, current) -> {
                acc[0] = acc[1];
                acc[1] = current;
            })
            .andExportFinish((acc) -> tuple2((T) acc[0], (T) acc[1]));
}

输出应为(previous, current)形式的元组。然后,您可以将滚动聚合再次应用于输出。为了简化输入问题,我有一对(id, amount)对。

Pipeline p = Pipeline.create();
p.drawFrom(Sources.<Integer, Long>mapJournal("map", START_FROM_OLDEST)) // (id, amount)
        .groupingKey(Entry::getKey)
        .rollingAggregate(previousAndCurrent(), (key, val) -> val)
        .rollingAggregate(AggregateOperations.summingLong(e -> {
            long prevValue = e.f0() == null ? 0 : e.f0().getValue();
            long newValue = e.f1().getValue();
            return newValue - prevValue;
        }))
        .drainTo(Sinks.logger());

JetConfig config = new JetConfig();
config.getHazelcastConfig().addEventJournalConfig(new EventJournalConfig().setMapName("map"));
JetInstance jet = Jet.newJetInstance(config);

IMapJet<Object, Object> map = jet.getMap("map");

map.put(0, 1L);
map.put(0, 2L);
map.put(1, 10L);
map.put(1, 40L);

jet.newJob(p).join();

这应该产生为输出:1, 2, 12, 42