Kafka:有效地将窗口聚合连接到事件

时间:2017-06-19 00:21:47

标签: apache-kafka-streams

我正在制作欺诈申请原型。我们经常会有"过去5天内现金交易总额等指标"我们需要与某个阈值进行比较,以确定我们是否会发出警报。

我们希望使用Kafka Streams来创建和维护聚合,然后创建具有原始事务字段和聚合的传入事务的增强版本。此增强记录由下游规则系统处理。

我想知道解决这个问题的最佳方法。我使用以下代码创建聚合的原型:

TimeWindows twoDayHopping TimeWindows.of(TimeUnit.DAYS.toMillis(2))
               .advanceBy(TimeUnit.DAYS.toMillis(1));
KStream<String, AdditiveStatistics> aggrStream = transactions
    .filter((key,value)->{
        return value.getAccountTypeDesc().equals("P") &&
               value.getPrimaryMediumDesc().equals("CASH");

    })
    .groupByKey()
    .aggregate(AdditiveStatistics::new,
               (key,value,accumulator)-> {                 
                   return AdditiveStatsUtil
                     .advance(value.getCurrencyAmount(),accumulator),
                              twoDayHopping,
                              metricsSerde,
                              "sas10005_store")
                } 
     .toStream()
     .map((key,value)-> {
                value.setTransDate(key.window().start());
                return new KeyValue<String, AdditiveStatistics>(key.key(),value);
            })
     .through(Serdes.String(),metricsSerde,datedAggrTopic);;

这将创建一个由商店支持的流,每个窗口的每个键都有一个记录。然后,我将原始事务流连接到此窗口,以生成主题的最终输出:

  JoinWindows joinWindow = JoinWindows.of(TimeUnit.DAYS.toMillis(1))
                                        .before(TimeUnit.DAYS.toMillis(1))
                                        .after(-1)
                                        .until(TimeUnit.DAYS.toMillis(2)+1);
    KStream<String,Transactions10KEnhanced> enhancedTrans = transactions.join(aggrStream,
                      (left,right)->{
                            Transactions10KEnhanced out = new Transactions10KEnhanced();
                            out.setAccountNumber(left.getAccountNumber());
                            out.setAccountTypeDesc(left.getAccountTypeDesc());
                            out.setPartyNumber(left.getPartyNumber());
                            out.setPrimaryMediumDesc(left.getPrimaryMediumDesc());
                            out.setSecondaryMediumDesc(left.getSecondaryMediumDesc());
                            out.setTransactionKey(left.getTransactionKey());
                            out.setCurrencyAmount(left.getCurrencyAmount());
                            out.setTransDate(left.getTransDate());
                            if(right != null) {
                                out.setSum2d(right.getSum());

                            }
                            return out;
                       },
                       joinWindow);

这会产生正确的结果,但它似乎运行了很长一段时间,即使记录数量很少。我想知道是否有更有效的方法来实现相同的结果。

1 个答案:

答案 0 :(得分:1)

配置问题:cf http://docs.confluent.io/current/streams/developer-guide.html#memory-management

通过将缓存大小设置为零来禁用缓存(cache.max.bytes.buffering中的参数StreamsConfig)将解决&#34;延迟&#34;交付到输出主题。

您可能还会阅读此博文,了解有关Streams设计的一些背景信息:https://www.confluent.io/blog/watermarks-tables-event-time-dataflow-model/