Flink 《数据流编程模型》(Dataflow Programming Model Levels of Abstraction)

目录

1. 抽象层次(levels of abstraction)

2. 程序和数据流(programs and dataflows)

3. 并行数据流(parallel Dataflows)

4. 窗口(Window)

5. 时间(Time)

6. 有状态操作(stateful operations)

7. 容错的检查点(checkpoints for fault tolerance)

8. 流的批处理(Batch on Streaming)


1. 抽象层次(levels of abstraction)

Flink 提供了多种不同层次的抽象来开发流/批程序。

  • 最底层的抽象仅仅提供了stateful streaming。它通过过程函数(Process Function)嵌入到DataStream API中。它允许用户自由的处理来自一个或多个流的事件,并且使用一致性容错状态。此外,用户还可以注册事件时间和处理时间回调,使得程序可以识别复杂的计算。
  • 在实践中,多数程序不会用到上面提到的低层抽象,而是使用DataStream API(有界/无界流)或者DataSet API(有界数据集)这样的核心API。这些流畅的API提供了数据处理的通用模块,比如用户指定的多种形式的转换操作:join,aggregation,window,state等等。这些API中处理的数据类型在不同编程语言中都以类的形式表达。

底层的过程函数(Process Function)与DataStream API集成,使得可以在底层执行某些特定操作。Dataset API为有界数据集提供了额外的元语,例如 loops/iterations。

  • Table API是一种围绕表,且可能会动态改变表的声明式领域专用语言(DSL)。Table API遵循下述关系模型:表有一个附加的schema(类似于关系型数据库),并且提供了相应的操作,例如,select,project,join,group-by,aggregate等。Table API程序声明式的定义了哪些逻辑操作需要做,而不是指定操作代码应该是什么样。尽管Table API可以通过多种类型的用户自定义函数扩展,但与Core API相比还是缺乏表现力,不过用起来更简洁。此外,Table API在执行前会通过优化器(该优化器应用了一些优化准则)做一些优化。

table 和 DataStream/Dataset之间可以无缝转换,使得程序可以混合使用Table API和DataStream API,DataSet API。

  • Flink提供的最高层次的抽象是SQL.这个抽象在语法和表达形式上都与Table API相似,但作用是将程序表示为SQL查询语句。SQL抽象与Table API交互紧密,SQL查询可以在Table API定义的表上执行。

2. 程序和数据流(programs and dataflows)

 Flink程序最基本的编程模块是stream和transformation.(Flink DataSet API中使用的DataSet在内部也是stream - 稍后再详细讨论)。从概念上讲, stream是数据记录流(可能永远不会结束),transformation是一种操作,它将一个或多个stream作为输入,产生一个或多个stream作为输出。

执行时,Flink程序会被映射成streaming dataflow,由streams和transformation operator(转换操作)构成。每一个dataflow都开始于一个或多个source,结束于一个或多个sink。类似于有向无环图(DAG)。尽管通过迭代结构特殊形式的循环是可以实现的,但是多数情况下我们都隐士的隐藏了这些操作。

 通常情况下,程序中的转换操作和dataflow中的算子是一一对应的。不过,有时候,一个转换操作可能由多个转换操作算子构成。

Sources和Sinks的相关文档请参阅streaming connectorsbatch connectors。转换操作参阅 DataStream operatorsDataSet transformations.

3. 并行数据流(parallel Dataflows)

Flink 本质上就是并行和分布式的。在执行期间,每一个stream都有一个或多个 stream分区,每一个operator都有一个或多个operator subtasks。这些operator subtasks之间是相互独立的,在不同的线程,甚至不同的机器或容器中执行。

operator subtasks的数量就是对应operator的并行度(parallelism)。一个stream的并行度是它产生的operator的数量。同一程序的不同operator可能会有不同水平的并行度。

 Stream可以在两个operator之间以一对一或重分配的形式传输数据:

  • 一对一stream保留了原有的分区和元素顺序(例如Source和map()操作)。这意味着map() operator的subtask[1]接收到的数据以及数据的顺序与Source operator的subtask[1]产生的一致。
  • 重分配stream会改变stream的分区(上述map()和keyBy/window之间,keyBy/window和sink之间)。根据不同的transformation,每个operator subtask向不同目标subtask发送数据。例如keyBy()(通过对key 哈希进行充分区),rebalanse()(随机重分区)。在重分配交换中,元素的顺序只在对应发送和接收的suntask中有保留(例如map()的subtask[1]和keyBy/window的subtask[2])。所以,在这个例子中,每个key中数据保留了顺序,但是到达sink的不同key的聚合结果的顺序是没有保障的。

配置和控制并行度的更多信息请参阅并行执行文档。

4. 窗口(Window)

聚合事件(例如count,sum)在stream和batch处理上有所不同。例如,统计stream中元素的个数是不可能的,因为流通常是没有边界的。所以流聚合(count,sum)使用窗口(window)划定范围,例如,统计过去5分钟内元素的个数,或者最近100个元素的和。

Windows可以是时间驱动(示例:每30秒)或数据驱动(示例:每100个元素)。通常可以区分不同类型的窗口,例如滚动窗口(没有重叠)、滑动窗口(有重叠)和会话窗口(由不活动的间隙隔开)。

 更多window示例可以查看blog post.更多细节请参阅window文档。

5. 时间(Time)

当提到streaming程序中的时间时,可以想到不同的时间:

  • 事件时间:事件创建的时间。通常描述为事件中的时间戳。例如,产生数据的传感器附加的时间,或者生产者服务附加的时间。Flink通过 timestamp assigner获取时间戳。
  • 摄入时间: 事件在source operator进入flink dataflow的时间。
  • 处理时间:operator执行基于时间操作时的本地时间。

关于如何处理时间的更多细节请参阅event time文档。

6. 有状态操作(stateful operations)

数据流中的一些操作只关注某一时刻的一个单独事件,而另一些操作则记录了多个事件的信息,这些操作称作有状态操作。

有状态操作的状态维护在一个嵌入式key/value存储中。这个状态是分区的,并且和有状态操作符读取的数据一起分区。因此,只能在应用了keyBy()函数之后的有键流上访问key/value状态,并且只能访问与当前时间的key关联的值。给流和状态取别名,可以保证所有的状态更新是本地操作,在没有事务负担的情况下保证一致性。这种对其操作使得Flink可以显示的分配state,调整分区。

更多信息请参考state

7. 容错的检查点(checkpoints for fault tolerance)

Flink通过stream replay和checkpointing组合实现容错。检查点与每个input stream中一个特殊点以及每个operator的对应状态有关。streaming dataflow可以从检查点恢复,并且,通过存储operator的状态,回放检查点中的事件可以保证数据一直性(exactly-once processing 语义)。

检查点间隔是一种将执行期间的容错开销与恢复时间(需要重放的事件数量)进行权衡的方法。

容错内部构件的描述提供了关于Flink如何管理检查点和相关主题的更多信息。启用和配置检查点的详细信息见检查点API文档。

8. 流的批处理(Batch on Streaming)

Flink将批处理程序作为流程序的一种特殊情况执行,其中流是有界的(元素数量有限)。数据集在内部被视为数据流。因此,上述概念同样适用于批处理程序,但有少数例外:

  • 批处理程序的容错不使用检查点。恢复通过完全重播流来实现。这是可能的,因为输入是有界的。这将使成本更接近于恢复,但会降低常规处理的成本,因为它可以避免检查点。
  • 数据集API中的有状态操作使用简化的内存/内核外数据结构,而不是键/值索引。
  • 数据集API引入了特殊的同步(基于前一步的)迭代,这只在有界流上是可能的。详细信息,请查看迭代文档

注:转载请注明出处。

参考:https://ci.apache.org/projects/flink/flink-docs-release-1.6/concepts/programming-model.html

猜你喜欢

转载自blog.csdn.net/Mathieu66/article/details/85207668