KafkaStreams介绍(三) –概念


说明:

本文是Confluent Platform 3.0版本中对于Kafka Streams的翻译。

原文地址:https://docs.confluent.io/3.0.0/streams/index.html

看了很多其他人翻译的文档,还是第一次翻译,有什么翻译的不好的地方还请指出。

 

这是Kafka Streams介绍的第三篇,以前的介绍如下:

http://blog.csdn.net/ransom0512/article/details/51971112

http://blog.csdn.net/ransom0512/article/details/51985983

 

 

在本机中,我们会总结Kafka Streams的关键概念,如果要了解更多详细信息,请参考架构和开发指南。

1.  Kafka 101

在设计上,经过深思熟虑的设计,KafkaStreams和Apache Kafka紧密集成,它使用kafka

作为其内部消息层。因此,熟悉Kafka的关键概念也很重要,特别是第一章入门和第四章架构设计。你特别应该明白:

l  角色:Kafka区分生产者(Producer),消费者(Consumer)和Brokers。Producer发布数据到Kafka Brokers,Consumer从Kafka Brokers中读取发布的数据。Producers和Consumers是完全分离的。一个Kafka集群由一个或者多个Broker组成。

l  数据:数据被存储在Kafka的Topics中。Topic是Kafka提供的最重要的抽象,它是Producer发布的同一类数据的抽象统称。在Kakfa中,每个Topic可以分为一个或者多个分区,这些分区分布在各个Brokers上面用于容错。

l  并发度:Kafka的分区数或者是给定的topic的数量是确定Kafka数据读取和写入的并发度的主要因素。由于Kafka Streams和kafka紧密集成,所以kafka Streams的并发度会在很大程度上收到Kafka并发度的影响。

 

2.  Stream(流)

Stream是KafkaStreams提供的最重要的抽象。它代表的是无限的,不断更新的数据集,其中无限意味着大小不明确或者无大小限制。一个Stream是一个有序的,允许重放的不可变的数据记录。其中数据记录被定义为一个容错的键值对。

3.  Stream Processing Application(流处理应用程序)

         一个流处理应用程序可以是任何集成了Kafka Streams库的程序。在实际使用中,它很有可能就是你的Java应用程序。他可以通过由一个或者多个Processor组成的拓扑结构来定义其计算逻辑。

4.  Processor Topology(处理拓扑)

处理拓扑定义了由流处理应用程序进行数据处理的计算逻辑。拓扑是由流(边)连接的流处理器的图。开发者可以通过Low-level API或者通过Kafka Streams的DSL来构建拓扑。


第四章的架构设计文档对于拓扑有更详细的描述。

5.  流处理器

流处理器用来处理拓扑中的各个节点。它代表拓扑中的每个处理步骤,用来完成数据转换功能。Kafka Streams为流处理器提供了标准操作例如Map,Filte和聚合等一系列开箱即用的功能。一个流处理器同一时间从上游接收一条输入数据,然后处理这条数据,产生一个或者多个输出记录到下个流处理器。

         KafkaStreams提供了两种方法来定义流处理器:

         KafkaStreams DSL API. 最常用的转换操作比如map和Filter,这样你就不必从头开始实现这些流处理器。

         Low-levelAPI:这些低级API允许开发人员定义和连接定制处理器和状态存储器进行交换。

6.  时间

流处理的一个很关键的方面就是时间,以及它是如何进行建模和整合的。比如,一些像Windows这样的窗口操作就是基于时间的界限所定义的。

         流处理上时间相关的概念主要如下:

  • 事件时间:事件或者记录产生的时间。即事件在源头最初创建的时间。事件时间在语义上通常要在产生的时候嵌入一个时间戳字段。

例如:如果事件产生于汽车GPS传感器报道的位置变化,那么相关的事件时间就是GPS传感器捕捉位置变化的时间。(也就是说,这个时间通常是在流处理系统以外产生的。)

  • 处理时间:流处理应用程序开始处理事件的时间点。(即事件进入流处理系统的时间。)这个处理时间到事件时间的间隔可能是毫秒,秒,小时,天或者更久远的时间。

例如:假设有一个应用程序用来读取和处理来自汽车GPS传感器报告的地理位置数据,并将其呈现给车队管理仪表盘。在这里,应用程序中的处理事件可能是毫秒或者秒(例如基于Apache的Kafka 和Kafka Stream流实时管道)或者小时(例如基于 Apache Hadoop或者Apache Spark的管道)。

  • 摄取时间:数据记录由KafkaBroker保存到 kafka topic对应分区的时间点。摄取时间类似事件时间,都是一个嵌入在数据记录中的时间戳字段。不同的是,摄取时间是由Kafka Broker附加在目标Topic上的,而不是附加在事件源上的。如果事件处理速度足够快,事件产生时间和写入Kafka的时间差就会非常小,这主要取决于具体的使用情况。因此,无法在摄取时间和事件时间之间进行二选一,两个语义是完全不同的。同时,数据还有可能没有摄取时间,比如旧版本的Kafka或者生产者不能直接生成时间戳(比如无法访问本地时钟。)。

 

事件时间和摄取时间的选择是通过在Kafka(不是KafkaStreams)上进行配置实现的。从Kafka 0.10.X起,时间戳会被自动嵌入到Kafka的Message中,可以根据配置选择事件时间或者摄取时间。配置可以在broker或者topic中指定。Kafka Streams默认提供的时间抽取器会将这些嵌入的时间戳恢复原样。因此,应用程序的有效时间语义上依赖于这种嵌入时时间戳读取的配置。请参考:Developer Guide<Timestamp Extractor>来获取更进一步信息。

Kafka Streams通过时间抽取器为每个记录分配时间戳。Sreams中每个记录的时间戳(可能是乱序)可以进行时间相关的操作,比如Join,也可以用于相同应用中的多个输入数据流同步。

时间提取器的具体实现方式主要是检索或者计算两种方式。可以根据数据记录的实际内容获取时间戳,也可以使用其他方式,比如本地时间戳。开发人员可以根据自己的业务需求选择不同的实现方式。

注意:Kafka Streams中的摄取时间和其他流处理系统略有不同,其他流处理系统中的摄取时间指的是从数据源中获取到数据的时间,而kafka Streams中,摄取时间是指记录被追加到Kakfa topic中的时间。

提示:使用时间是,你也应该保证时区和日历的其他方面是正确同步的,或者至少是了解之间的差异。例如,统一使用UTC或者Unix时间,指定时间信息格式一致,如统一精确到秒,你也不要混用不同语义的时间。

7.  有状态的流处理

一些流处理应用不需要状态,这意味着每个消息的处理都是彼此独立的。如果你只需要进行消息转换,或者基于某些条件进行筛选,那么你的流处理应用程序的拓扑会非常简单。

然而,能够保存状态,就是的流处理系统可以应用在更多场景。你可以进行Join,Group by或者aggregate操作,Kafka Streams DSL供了很多这样的包含状态的DSL。

8.  流和表的双重性

在我们讨论Kafka Stream的aggregate等操作之前,我们必须先介绍表,以及最重要的表和流之间的关系,即流和表的双重性。本质上,这种双重性意味着一个流可以作为表,反之亦然。Kafka的Log compact功能,就是利用了这种双重性。

表的简单形式是一个KV对的集合,也可以称为Map或者关联数组。

说明:为了使得这一章节简答,我们会跳过复合键,MultiSet等的讨论。 

有如下一张表:


下面这张Stream-Table描述了流和表之间双重性的密切关系。

Stream as table:流可以被认为是一张表,其中,流上的每条数据记录代表了表的状态变化的更新日志。一个流就是一张变相的表,它可以通过重建日志的方式很容易就变成一个真正的表。同样,一个更具普适性的例子– 例如从网页事件流中统计用户网页浏览的总数– 返回一张表(这里用Key和Value分别表示用户和其浏览量的总数。)

Table as Stream: 一个表可以被认为是流上一个时间点的快照。表上的每行记录,都代表该键的最新值。因此,一个表示一种变相的流,它可以通过遍历表中的每个KV对很容易变成一个真正的流。

让我们通过如下的例子进行说明:假设有一张跟踪用户浏览网页总数的统计表,随着时间的推移,当处理新的网页浏览记录的时候,表中的状态会被相应的更新,这里,不同时间点会有不同的变化,这种变化可以表示为一个changlog的流。


有意思的是,由于流和表的双重性,使用相同的流可以重构原始表(第三列)。


相同的机制还被用于如下场景,例如,数据库之间通过数据捕获机制(CDC change data capture)进行复制,Kafka Streams通过在多个节点内复制存储的状态来保证其容错性。流和 表的双重性的概念在Kafka Streams中极其重要,接下来的章节,我们将重点说明这些。

9.  KStream(事件流)

说明:只有Kafka Streams的DSL才有KStream的概念。

一个KStream是一个事件流,其中每条事件记录代表了无限的包含数据的数据集的抽象。用表来解释流的概念,数据的记录始终被解释为Insert,只有追加,因为没有办法替换当前已经存在的相同key的行数据。比如戏弄卡交易,一个页面视图或者服务器日志。

为了说明这一点,我们可以想象有如下两个记录被发送到流。

("alice", 1) -->("alice", 3)

     如果你的流处理一弄程序是要汇总每个用户的键值,他就会返回4,因为第二个记录不会被视为当前记录的更新。如果是要比较使用最新的Key值,那么alice就会返回3.

10.        KTable(changelog流)

说明:只有Kafka Streams的DSL才有KTable的概念。

         一个KTable是一个changlog更新日志流。其中每个数据记录代表一个更新的抽象。准确来说,一个数据记录的值被认为是相同Key的最后一个值的更新结果。对于该表在流上的解释,可以被认为是一个更新,因为任何相同Key值的记录都会被更新。

         为了说明这一点,我们可以假设有以下两个数据记录被发送到流。

("alice", 1) -->("alice", 3)

如果你的流处理应用程序要总结每个用户的总值,它会为alice返回3,因为第二个记录会被视为记录的更新。而KStream会将这种行为返回4.

说明:Kafka日志压缩的影响, 考虑KStream和KTable的另一种形式,如果一个KTable存储到Kafka的topic中,你就需要启用Kafka的日志压缩功能以节省空间。

然而,这种方式在KStream的情况下是不安全的,因为,一旦开启日志压缩,Kafka就会删除比较旧的Key值,这样就会破坏数据的语义。以数据重放为例,你会突然得到一个值为3的alice,而不是4,因为以前的记录都被日志压缩功能删除了。因此,日志压缩在KTable中使用是安全的,但是在KStream中使用是错误的。

我们已经看到了流和表的双重性在changlog中的例子,另外一个例子是关系型数据库中的捕获数据更新日志(CDC changelog data capture)记录,表示该行在数据库中的插入,更新或者删除。

KTable还提供了通过key查找数据值得功能,该查找功能可以用在Join等功能上。

11.        窗口

一个流处理器可能需要将数据划分为多个时间段,这就是流上窗口。这通常在Join或者aggregation聚合等保存本地状态的处理程序中使用。

Kafka StreamsDSL API提供了可用的窗口操作,用户可以指定数据在窗口中的保存期限。这就允许Kafka Streams在窗口中保留一段时间的旧数据以等待其它晚到的数据。如果保留期过了之后数据才到达,这条消息就不能被处理,会被丢掉。

实时的流处理系统中,数据乱序总是存在的,这主要取决于数据在有效时间内如何进行处理。对于在正处于处理期的时间内的数据,如果数据乱序,延迟到达,在语义上就可以被正常处理,如果数据到达时候,已经不在处理期,那么这种数据就不适合处理期的语义,只能被丢弃掉。

12.        Join

Join操作负责在Key上对两个流的记录进行合并,并产生新流。一个基于流上的Join通常是基于窗口的,否则所有数据就都会被保存,记录就会无限增长。

         KafkaStreams DSL支持不同的Join操作,比如KStram和KStream之间的Join,以及KStream和KTable之间的Join。

13.        Aggregations

聚合操作需要一个输入流,并且以多个输入记录为单位组合成单个记录并产生新流。常见的聚合操作有count和sum。流上的聚合也必须基于窗口进行,否则数据和join一样都会无限制增长。

在Kafka Streams的DSL中,一个聚合输入流可以是KStream形式或者KTable形式,但是输出流永远都是KTable。这就使得Kafka Streams的输出结果会被不断更新,这样,当有数据乱序到达之后,数据也可以被及时更新,因为最终输出是KTable,新key会覆盖旧值。

  • 4
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值