Apache Flink 数据流编程模型

抽象级别

Flink提供不同层次的抽象来开发流/批处理应用程序。

这里写图片描述

最低层次的抽象只提供有状态的流。它通过流程函数嵌入到DataStream
API
中。它允许用户自由地处理来自一个或多个流的事件,并使用一致的容错状态。此外,用户可以注册事件时间和处理时间回调,允许程序实现复杂的计算。

在实践中,大多数应用程序不需要上面描述的低级抽象,而是针对像DataStream API(有界/无界流)和 DataSetAPI(有界的数据集)这样的CoreAPIs进行编程。这些流畅的api为数据处理提供了通用的构建块,如各种形式的用户指定的转换、连接、聚合、窗口、状态等。这些api中处理的数据类型以各自的编程语言的类来表示。

低层次的操作方法与DataStreamAPI集成在一起,这使得为特定的操作实现底层抽象成为可能。数据集API提供了有界数据集的额外原语,如循环/迭代。

Table API是一个以表为中心的声明型DSL,它可能是动态变化的表(当表示流的时候)。表API遵循(扩展)关系模型:表有一个附加模式(类似于关系数据库表)和API提供了类似的操作,如选择、项目,加入,group
by、聚合等。TableAPI程序以声明的方式定义逻辑操作应该做什么而不是指定操作的代码看起来如何。尽管表API可以通过各种用户定义函数进行扩展,但它的表达能力比核心API更少,但是使用起来更简洁(编写的代码更少)。此外,表API程序还通过一个优化器,在执行之前应用优化规则。

可以无缝地转换tables 和数据存储/数据集,允许程序混合Table API 和DataStream和DataSet API。

Flink提供的最高抽象是SQL。这种抽象与Table
API类似于语义和表达性,但表示程序为SQL查询表达式。SQL抽象与表API密切交互,SQL查询可以通过Table API中定义的表执行

数据流编程

Flink程序的基本构件是流和转换。

从概念上讲,流是数据记录的(可能是无限的)流,而转换是一个操作,它以一个或多个流作为输入,结果产生一个或多个输出流。

执行时,Flink程序被映射到流数据流,由流和转换操作组成。每个数据都以一个或多个源开始,并以一个或多个接收器结束。数据流类似于任意的有向非循环图(DAG)。

这里写图片描述

通常,程序中的变换和数据流中的运算符之间存在一对一的对应关系。然而,有时,一个变换可能由多个转换组成。

并行数据流

Flink中的程序本质上是并行和分布式的。

在执行期间,流具有一个或多个流分区,并且每个运算符具有一个或多个运算子任务。操作子任务彼此独立,并在不同的线程中执行,也可能在不同的机器或容器中执行。

这里写图片描述

流可以以一对一(或转发)模式或重新分配模式在两个operators 之间传输数据:

一对一流(One-to-one streams)(例如上图中的Source和map()operator之间)保留元素的分区和排序。这意味着map()操作符的子任务[1]将以相同的顺序看到相同的元素,因为它们是由源操作的子任务[1]生成的。

重分配流(在map()和keyBy / window之间,以及keyBy / window和Sink之间)即改变流的分区。每个操作员子任务根据所选择的转换将数据发送到不同的目标子任务。示例是keyBy()(通过哈希键重新分区),broadcast()或rebalance()(其随机重新分区)。在重新分配交换中,元素之间的排序仅保留在每对发送和接收子任务中。(例如map()的子任务[1]和keyBy / window的子任务[2]),所以在这个例子中,每个键中的顺序被保留,但并行性确实引入关于不同键的聚合结果到达接收器的顺序的非确定性。

有关配置和控制并行性的详细信息,请参见并行执行文档

猜你喜欢

转载自blog.csdn.net/qq_38692223/article/details/72716674