Big Data

flink概念

2019-06-27  本文已影响0人  盗梦者_56f2

数据流编程模型

抽象层次

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


抽象层次

程序和数据流

Flink程序的基本构建块是streams和transformations。(请注意,Flink的DataSet API中使用的DataSet也是内部流 - 稍后会详细介绍。)从概念上讲,streams是(可能永无止境的)数据记录流,而transformations是将一个或多个流作为输入,并产生一个或多个输出流的一个或多个流操作。
执行时,Flink程序映射到streaming dataflows,包括流和转换运算符。每个数据流都以一个或多个sources开头,并以一个或多个sinks结束。数据流类似于任意有向无环图 (DAG)。虽然通过迭代构造允许特殊形式的循环,但为了简单起见,我们将在大多数情况下对此进行隐藏。

并行数据流

Flink中的程序本质上是并行和分布式的。 在执行期间,流具有一个或多个流分区(stream partitions),并且每个运算符具有一个或多个运算符子任务(operator subtasks)。 运算符子任务彼此独立,并且可以在不同的线程中执行,并且可能在不同的机器或容器上执行。

运算符子任务的数量是该特定运算符的并行度。 流的并行性始终是其生成运算符的并行性。 同一程序的不同运算符可能具有不同的并行级别。

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

Windows

聚合事件(例如,计数,总和)在流上的工作方式与批处理方式不同。例如,不可能计算流中的所有元素,因为流通常是无限的(无界)。相反,流上的聚合(计数,总和等)由窗口限定,例如“在最后5分钟内计数”或“最后100个元素的总和”。
Windows可以是时间驱动的(例如:每30秒)或数据驱动(例如:每100个元素)。一个典型地区分不同类型的窗口,例如翻滚窗口(tumbling windows)(没有重叠), 滑动窗口(sliding windows)(具有重叠)和会话窗口(session windows)(由不活动的间隙打断)。

Time

当在流程序中引用时间(例如定义窗口)时,可以参考不同的时间概念:

有状态操作

虽然数据流中的许多操作只是一次查看一个单独的事件(例如事件解析器),但某些操作会记住多个事件(例如窗口操作符)的信息。这些操作称为有状态。
有状态操作的状态是在可以看作是嵌入式键/值存储区中维护的。状态与由有状态操作符读取的流一起严格地划分和分布。因此,只有在keyBy()函数之后的键控流上才能访问键/值状态,并且只能访问与当前事件的键关联的值。对流和状态的键进行对齐可以确保所有状态更新都是本地操作,从而保证一致性,而不会产生事务开销。这种对齐还允许Flink重新分配状态并透明地调整流分区。

容错检查点(Checkpoints for Fault Tolerance)

Flink使用流重放(stream replay)和检查点(checkpointing)的组合实现容错。检查点与每个输入流中的特定点以及每个操作符的对应状态相关。通过恢复操作符的状态并从检查点的点重放事件,可以从检查点恢复流数据流,同时保持一致性(exactly-once处理语义)。
检查点间隔是在执行期间用恢复时间(需要重放的事件的数量)来折衷容错开销的手段。

Batch on Streaming

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


分布式运行环境

任务和操作符链(Tasks and Operator Chains)

对于分布式执行,Flink将操作符子任务链接到任务中,每个任务由一个线程执行。 将操作符链接到任务是一项有用的优化:它可以减少线程到线程切换和缓冲的开销,并在降低延迟的同时提高整体吞吐量。

Job Managers, Task Managers, Clients

Flink运行时包含两种类型的进程:

JobManagers和TaskManagers可以通过多种方式启动:直接在计算机上作为独立集群,在容器中,或由YARN或Mesos等资源框架管理。TaskManagers连接到JobManagers,宣布自己可用,并被分配工作。
client不是运行时和程序执行的一部分,但用于准备数据流并将数据流发送到JobManager。 之后,客户端可以断开连接或保持连接以接收进度报告。 客户端作为触发执行的Java / Scala程序的一部分运行,或者在命令行进程中运行./bin/flink run ....

任务槽和资源(Task Slots and Resources)

每个worker(TaskManager)都是一个JVM进程,可以在不同的线程中执行一个或多个子任务。为了控制worker接受的任务数量,worker有所谓的任务槽(至少一个)。
每个任务槽代表TaskManager的固定资源子集。例如,具有三个槽的TaskManager将其1/3的内存专用于每个槽。切换资源意味着子任务不会与来自其他作业的子任务竞争内存,而是具有一定量的保留内存。请注意,这里没有CPU隔离; 当前槽只分离任务的内存。
通过调整任务槽的数量,用户可以定义子任务如何相互隔离。每个TaskManager有一个槽意味着每个任务组在一个单独的JVM中运行(例如,可以在一个单独的容器中启动)。拥有多个槽意味着更多子任务共享同一个JVM。同一JVM中的任务共享TCP连接(通过多路复用)和心跳消息。还可以共享数据集和数据结构,从而减少每任务开销。
默认情况下,Flink允许子任务共享槽,即使它们是不同任务的子任务,只要它们来自同一个Job。 结果是一个槽可以保存作业的整个管道。 允许槽共享有两个主要好处:

状态后端(State Backends)

存储键/值索引的确切数据结构取决于所选的状态后端。一个状态后端将数据存储在内存中的哈希映射中,另一个状态后端使用RocksDB作为键/值存储。除了定义保存状态的数据结构之外,状态后端还实现逻辑以获取键/值状态的时间点快照,并将该快照存储为检查点的一部分。

保存点(Savepoints)

用Data Stream API编写的程序可以从保存点恢复执行。保存点允许更新程序和Flink群集,而不会丢失任何状态。

保存点是手动触发的检查点,它捕获程序的快照并将其写入状态后端,他们依靠常规的检查点机制。在执行期间,程序会定期在工作节点上创建快照并生成检查点。对于恢复,仅需要最后完成的检查点,并且一旦有新检查点完成,就可以安全地丢弃旧检查点。

保存点与这些定期检查点类似,不同之处在于它们由用户触发,并且在较新的检查点完成时不会自动过期。可以从命令行创建保存点,也可以通过REST API取消作业。


上一篇下一篇

猜你喜欢

热点阅读