04-20.eri-test 如何在Kafka Streams中使用状态操作?

Kafka Streams API博客系列的第一部分介绍了无状态的诸如过滤地图等等。在这一部分,我们将探索有状态的Kafka Streams DSL API中的操作。 它着重于聚合操作,例如骨料计数减少以及相关概念的讨论。

Aggregation

聚合操作应用于相同键的记录。 Kafka Streams支持以下聚合-骨料计数减少。 如先前的博客所述,分组是聚合的先决条件。 你可以跑通过。..分组(或其变体)在KStream或一个桌子导致KGroupedStream和分组表分别

桌子分组之前在无状态操作博客中介绍

骨料

骨料功能有两个关键组成部分-初始化器聚合器。 收到第一条记录后,初始化器被调用,并被用作聚合器。 对于后续记录,聚合器将当前记录与计算的聚合(直到现在)一起使用来进行计算。 从概念上讲,这是对无限数据集执行的有状态计算-这是有状态的,因为计算当前状态会考虑当前状态(键值记录)以及最新状态(当前聚合)。 这可以用于诸如移动平均,总和,计数等方案。

这是一个如何计算计数的示例,即接收特定密钥的次数

code examples are available on GitHub

        StreamsBuilder builder = new StreamsBuilder();
        KStream<String,String> stream = builder.stream(INPUT_TOPIC);

        桌子<String,Count> 骨料 = stream.通过...分组Key()
                .aggregate(new Initializer<Count>() {
                    @Override
                    public Count apply() {
                        return new Count("",0);
                    }
                }, new 聚合器<String, String, Count>() {
                    @Override
                    public Count apply(String k, String v, Count aggKeyCount) {
                        Integer currentCount = aggKeyCount.getCount();
                        return new Count(k, currentCount + 1);
                    }
                });


        aggregate.toStream()
                 .map((k,v) -> new KeyValue<>(k, v.getCount()))
                 .to(COUNTS_TOPIC, Produced.with(Serdes.String(), Serdes.Integer()));

计数

count是一种通常使用的聚合形式,它是作为一流操作提供的。 将流记录按键分组后(KGroupedStream),您可以使用此操作计算特定密钥的记录数。

aggregate可以用一个方法调用来代替做事方式!

        StreamsBuilder builder = new StreamsBuilder();
        KStream<String, String> stream = builder.stream(INPUT_TOPIC);

        stream.通过...分组Key().count();

减少

您可以使用减少合并价值流。 的aggregate前面介绍的操作是的广义形式reduce。 您可以实现以下功能, , 最大值等。这是一个例子最大值

        StreamsBuilder builder = new StreamsBuilder();
        KStream<String, Long> stream = builder.stream(INPUT_TOPIC, Consumed.with(Serdes.String(), Serdes.Long()));

        stream.groupByKey()
                .reduce(new Reducer<Long>() {
                    @Override
                    public Long apply(Long currentMax, Long v) {
                        Long max = (currentMax > v) ? currentMax : v;
                        return max;
                    }
                }).toStream().to(OUTPUT_TOPIC);

        返回builder.build();

请注意,所有聚合操作都会忽略带有空值密钥是显而易见的,因为这些功能集的目的是对特定密钥的记录进行操作

Aggregation和state stores

在以上示例中,汇总值被推送到输出主题-尽管这不是强制性的。 可以将聚合结果存储在本地状态存储中。 这是一个例子:

        StreamsBuilder builder = new StreamsBuilder();
        KStream<String, String> stream = builder.stream(INPUT_TOPIC);

        stream.groupByKey().count(Materialized.as("计数店"));

在上面的示例中,count还创建一个名为的本地状态存储count-store然后可以使用交互式查询自省。

这些状态存储可以在内存中,也可以使用岩石数据库。 这允许可扩展性由于每个状态存储都位于特定的Kafka Streams应用程序本地,该应用程序处理主题的不同分区的输入-因此,总体状态分布在(潜在的)应用程序的多个实例中(除非全局表s)。 另一个关键属性是高可用性因为这些状态存储的内容已备份为Kafka变更日志又名压实的提供高可用性的主题(尽管可以禁用)-如果应用程序实例崩溃,则可以从Kafka本身还原状态存储内容

分组表

一种分组表groupBy*操作在桌子。 就像KGroupedStream, 有一个分组表是对一个集合应用聚合的先决条件桌子aggregate, countreduce以相同的方式工作KGroupedTable就像他们使用KGrou`pedStream一样。 但是,有一个重要的区别需要强调。

一种KTable在概念上与KStream从某种意义上说,它表示某个时间点的数据快照(非常类似于数据库表)。 它是一个可变的实体,而不是KStream它代表一个不变的+无限的记录序列。 考虑到这一差异,aggregate and reduce在一个功能KGroupedTable还添加一个额外的Aggregator(通常称为减法器),并且在更新密钥或空值获得值。

加窗

有状态的Kafka Streams操作也支持窗口ing。 这使您可以将流处理管道的范围限定为特定的时间窗口/范围,例如 跟踪号 每分钟链接点击数或否。 每小时的唯一身份浏览量

去表演Windowed聚合一组记录,则必须创建一个KGroupedStream(如上所述)使用groupBy在一个KStream然后使用窗口化操作(有两种重载形式)。 您可以在传统窗口(滚动,跳动或滑动)或基于会话的时间窗口之间进行选择

使用windowedBy(Windows<W> windows)在一个KGroupedStream返回一个TimeWindowedKStream您还可以在其上调用上述聚合操作。 例如 如果您希望在特定时间范围内(例如5分钟)点击次数,请选择滚动时间窗口。 这样可以确保在给定的时间范围内清楚地分隔记录,即从user1的上午10点至10:05 AM的点击将分别进行汇总(计数),并且新的时间段(窗口)将从10:06 AM开始,在此期间 点击计数器重置为零并再次计数

`
StreamsBuilder builder = new StreamsBuilder();
KStream stream = builder.stream(INPUT_TOPIC);

TimeWindowedKStream windoweded = stream.groupByKey()。windowedBy(TimeWindows.of(Duration.ofMinutes(5)));

windowed.count()。toStream()。to(OUTPUT_TOPIC);
`

其他窗口类型包括:

  • 翻滚永远不会重叠的时间窗口,即一条记录只会是一个窗口的一部分...
  • ...与跃迁可以在一个或多个时间范围/窗口中显示记录的时间窗口
  • 滑行时间窗口适合与加盟操作一起使用

有状态操作的另一种类型是Joining。 这是一个广泛的话题,其本身值得一整篇文章(或其他系列文章?)

如果您要考虑“会话”,即活动时间间隔为已定义的不活动间隔,请使用windowedBy(SessionWindows窗口)返回一个SessionWindowedKStream.

`
StreamsBuilder builder = new StreamsBuilder();
KStream stream = builder.stream(INPUT_TOPIC);

    stream.groupByKey().windowedBy(SessionWindows.with(Duration.ofMinutes(5)))
                       .toStream().to(OUTPUT_TOPIC);

return builder.build();
`

这就是Kafka Streams博客系列的全部内容。 请继续关注下一部分,它将演示如何使用内置的测试实用程序来测试Kafka Streams应用程序。

References

请不要忘记查看以下有关Kafka Streams的资源

from: https://dev.to//itnext/how-to-use-stateful-operations-in-kafka-streams-4ia1

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值