Flink 编程模型
1.流式数据流
Flink程序的基本构建块是流和转换 。 (请注意,Flink的DataSet API中使用的DataSet也是内部流-稍后将进行更多介绍。)从概念上讲, 流是数据记录流(可能永无止境),而转换是将一个或多个流作为一个操作的操作。输入,并因此产生一个或多个输出流。
执行时,Flink程序将映射到由流和转换运算符组成的流 数据 流 。 每个数据流都以一个或多个源开始,并以一个或多个接收器结束。 数据流类似于任意有向无环图 (DAG)。
2.并行数据流
Flink中的程序本质上是并行的和分布式的。 在执行期间,一个流具有一个或多个流分区 ,并且每个运算符具有一个或多个运算符子任务 。 操作员子任务彼此独立,并在不同的线程中执行,并且可能在不同的机器或容器上执行
流可以按一对一 (或转发 )模式或重新分配模式在两个运算符之间传输数据:
-
一对一的流(例如,上图中的Source和map()运算符之间)保留元素的分区和排序。 这意味着map()运算符的subtask [1]将看到与Source运算符的subtask [1]产生的元素相同的顺序。
-
重新分配流(如上面的map()和keyBy / window之间以及keyBy / window和Sink之间 )会更改流的分区。例如: keyBy() (通过散列键重新分区), broadcast()或rebalance() (随机重新分区)。 在重新分发交换中,元素之间的顺序仅保留在每对发送和接收子任务中(例如map()的subtask [1]和keyBy / window的subtask [2])。 因此,在此示例中,保留了每个键内的顺序,但是并行性的确引入了不确定性,即不同键的聚合结果到达接收器的顺序。
3.窗口
汇总事件(例如,计数,总和)在流上的工作方式与批处理中的不同。 例如,不可能计算流中的所有元素,因为流通常是无限的(无界)。 相反,流的聚合(计数,总和等)由窗口确定范围,例如“过去5分钟内的计数”或“最近100个元素的总和” 。
Windows可以是时间驱动的 (例如:每30秒)或数据驱动的 (例如:每100个元素)。 通常可以区分不同类型的窗口,例如滚动窗口 (无重叠), 滑动窗口 (有重叠)和会话窗口 (由不活动的间隙打断)。
4.基于流的批处理
Flink执行批处理程序作为流程序的特例,在这种情况下,流是有界的(元素数量有限)。 DataSet在内部被视为数据流。 因此,以上概念以同样的方式适用于批处理程序,也适用于流式程序,但有少量例外:
-
批处理程序的容错功能不使用检查点。 通过完全重播流来进行恢复。 这是可能的,因为输入是有界的。 这将成本更多地推向了恢复,但由于避免了检查点,因此使常规处理的成本降低了。
-
DataSet API中的状态操作使用简化的内存中/内核外数据结构,而不是键/值索引。
-
DataSet API引入了特殊的同步(基于超步)迭代,仅在有限流上才有可能。 有关详细信息,请查看迭代文档 。
233
参考
https://ci.apache.org/projects/flink/flink-docs-release-1.10/zh/concepts/programming-model.html