flink学习---flink简单认识

flink 定义

flink 是分布式流和批计算的开源框架,Flink的核心是一个流数据流引擎,它为数据流上的分布式计算提供数据分发、通信和容错功能。Flink在流引擎之上构建批处理,覆盖本地迭代支持、托管内存和程序优化。

flink 概念

 Dataflow Programming Model    流编程模型

   Levels of Abstraction

Flink提供了不同级别的抽象去开发流或批应用程序:

   Programming levels of abstraction

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

      大多数应用程序不需要上面描述的低层抽象,而是根据核心API (DataStream API(有界/无界流)和DataSet API(有界数据集)进行编程。这些连贯api为数据处理提供了常见的构建块,比如用户指定的各种形式的转换、连接、聚合、窗口、状态等。在这些api中处理的数据类型用各自的编程语言表示为类。低层流程函数与DataStream API集成,使得仅对某些操作进行低层抽象成为可能。DataSet API在有界数据集上提供了额外的原语,比如循环/迭代。

       表API是一个以表为中心的声明性DSL,表可以(在表示流时)动态地更改表。表API遵循(扩展的)关系模型:表有一个附加的模式(类似于关系数据库中的表),而API提供了类似的操作,如select、project、join、group-by、aggregate等。表API程序声明性地定义应该执行什么逻辑操作,而不是确切地指定操作代码的外观。虽然表API可以通过各种类型的用户定义函数进行扩展,但是它比核心API更缺乏表现力,但是使用起来更简洁(编写的代码更少)。此外,表API程序还需要经过一个在执行之前应用优化规则的优化器。可以在表和DataStream/DataSet之间无缝转换,允许程序混合表API和DataStream和DataSet API。

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

Programs and Dataflows

      Flink程序的基本构建块是流和转换。(注意,在Flink的DataSet API中使用的数据集也是内部流的——稍后会详细介绍)。从概念上讲,流是数据记录的流(可能永远不会结束),转换是一个操作,它接受一个或多个流作为输入,并生成一个或多个输出流。

     当执行时,Flink程序被映射到流数据流,由流和转换操作符组成。每个数据流开始于一个或多个源,结束于一个或多个接收器。数据流类似于任意有向无环图(DAGs)。虽然通过迭代构造允许使用特殊形式的循环,但是为了简单起见,我们将在大多数情况下忽略这一点。

A DataStream program, and its dataflow.

Parallel Dataflows

Flink中的程序本质上是并行和分布式的。在执行期间,一个流有一个或多个流分区,每个操作符有一个或多个操作符子任务。操作符子任务彼此独立,并在不同的线程中执行,也可能在不同的机器或容器上执行。运算符子任务的数量是该特定运算符的并行度。流的并行性总是它的产生算子的并行性。同一程序的不同操作符可能具有不同级别的并行性。treams可以在两个操作符之间以一对一(或转发)模式传输数据,也可以采用重新分发模式。

A parallel dataflow

Windows

Windows可以是时间驱动的(例如:每30秒),也可以是数据驱动的(例如:每100个元素)。一个典型的例子是区分不同类型的窗口,比如翻滚窗口(没有重叠)、滑动窗口(有重叠)和会话窗口(中间有一个不活动的间隙)。

Time- and Count Windows

Time

当提到流媒体程序中的时间(例如定义windows)时,可以指不同的时间概念:

Event Time 事件事件是创建事件的时间。它通常由事件中的时间戳描述,例如由生产传感器或生产服务附加的时间戳。Flink通过时间戳分配程序访问事件时间戳。

Ingestion time 摄取时间是事件在源操作符处进入Flink数据流的时间。

Processing Time 处理时间是每个执行基于时间的操作的操作符的本地时间。

Event Time, Ingestion Time, and Processing Time

Stateful Operations

将流的键与状态对齐可以确保所有状态更新都是本地操作,从而确保一致性,而不需要事务开销。这种对齐还允许Flink重新分配状态并透明地调整流分区。

State and Partitioning

Checkpoints for Fault Tolerance

    Flink使用流回放和检查点的组合实现容错。检查点与每个输入流中的特定点以及每个操作符的对应状态相关。流数据流可以从检查点恢复,同时通过恢复操作符的状态并从检查点重播事件来保持一致性(精确地说,一次处理语义)。

    检查点间隔是一种用恢复时间(需要重放的事件数量)来抵消执行期间容错开销的方法。

    容错内部的描述提供了关于Flink如何管理检查点和相关主题的更多信息。启用和配置检查点的详细信息在检查点API文档中。键/值存储。状态与有状态操作符读取的流一起严格地分区和分布。因此,只有在keyBy()函数之后的键控流上才能访问键/值状态,并且只能访问与当前事件的键关联的值。将流的键与状态对齐可以确保所有状态更新都是本地操作,从而确保一致性,而不需要事务开销。这种对齐还允许Flink重新分配状态并透明地调整流分区。

Batch on Streaming

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

批处理程序的容错不使用检查点。恢复是通过完全重放流来实现的。这是可能的,因为输入是有界的。这使得恢复的成本更高,但是使常规处理更便宜,因为它避免了检查点。

DataSet API中的有状态操作使用简化的内存/内核外数据结构,而不是键/值索引。

DataSet API引入了特殊的同步(基于超步)迭代,这只可能在有界流上实现。有关详细信息,请查看iteration文档。

 Distributed Runtime Environment

Tasks and Operator Chains

对于分布式执行,将操作符子任务一起链接到任务中。每个任务由一个线程执行。将操作符链接到任务中是一种有用的优化:它减少了线程到线程切换和缓冲的开销,增加了总体吞吐量,同时降低了延迟。可以配置链接行为;有关详细信息,请参阅链接文档。

下图中的示例数据流使用5个子任务执行,因此使用5个并行线程。

Operator chaining into Tasks

Job Managers, Task Managers, Clients

The Flink runtime consists of two types of processes:

  • The JobManagers (also called masters) coordinate the distributed execution. They schedule tasks, coordinate checkpoints, coordinate recovery on failures, etc.

    There is always at least one Job Manager. A high-availability setup will have multiple JobManagers, one of which one is always the leader, and the others are standby.

  • The TaskManagers (also called workers) execute the tasks (or more specifically, the subtasks) of a dataflow, and buffer and exchange the data streams.

    There must always be at least one TaskManager.The client is not part of the runtime and program execution, but is used to prepare and send a dataflow to the JobManager. After that, the client can disconnect, or stay connected to receive progress reports. The client runs either as part of the Java/Scala program that triggers the execution, or in the command line process 

  • The processes involved in executing a Flink dataflow

Task Slots and Resources

每个worker (TaskManager)都是一个JVM进程,可以在单独的线程中执行一个或多个子任务。为了控制worker 接受多少任务,worker 具有所谓的Task Slots(至少一个)。

每个Task Slots表示TaskManager资源的一个固定子集。注意,这里没有发生CPU隔离;当前插槽只分隔任务的托管内存。

通过调整Task Slots的数量,用户可以定义子任务如何彼此隔离。每个TaskManager有一个Task Slots意味着每个任务组运行在单独的JVM中(例如,可以在单独的容器中启动JVM)。拥有多个Task Slots意味着更多的子任务共享同一个JVM。相同JVM中的任务共享TCP连接(通过多路复用)和心跳消息。它们还可以共享数据集和数据结构,从而减少每个任务的开销。

TaskManagers with shared Task Slots

State Backends

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

checkpoints and snapshots

Savepoints

在数据流API中编写的程序可以从Savepoints恢复执行。Savepoints允许在不丢失任何状态的情况下更新程序和Flink集群。

Savepoints是手动触发的检查点,它获取程序的快照并将其写入state backend。它们依赖于常规的检查点机制。在执行过程中,程序定期在工作节点上快照并生成检查点。对于恢复,只需要最后一个完成的检查点,而旧的检查点可以在新检查点完成时安全地丢弃。

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

猜你喜欢

转载自blog.csdn.net/wjandy0211/article/details/95210876
今日推荐