初识Flink | 青训营笔记

72 阅读6分钟

这是我参与「第四届青训营 」笔记创作活动的第2天

大数据:无法在一定时间内用常规工具对其进行获取存储管理和处理的数据集合,价值密度很低。

大数据实时性价值:监控场景:监控业务系统健康状态;金融风险:检测异常交易行为;实时推荐。

image.png 大数据发展史:

史前:oracle 单机 传统数据仓库 ABM大型机

Hadoop:分布式、MapReduce、离线计算(MapReduce计算需要落盘,计算接口原始)

Spark:批处理、流处理、SQL高阶API、内存迭代计算

Flink:流处理、实时更快、流批一体、Steaming/Batch SQL

image.png Spark Streaming:批处理模式,将无限流切成无限小的批,不断调度小的Spark作业,可以做到Mini-batch Exactly-Once(延迟较高、秒级别) 和RDD based Checkpoint。

Flink结合Kakfa的两阶段提交可以做到完整的Exactly-Once语义(低延迟、毫秒级),基于(Chandy-Lamport)Checkpoint。

  image.png

Flink

Apache Flink is a framework and distributed processing engine for stateful computations over unbounded and bounded data streams. Flink has been designed to run in all common cluster environments, perform computations at in-memory speed and at any scale。

Flink的世界观是数据流 对 Flink ⽽⾔,其所要处理的主要场景就是流数据,批数据只是流数据的⼀个极限特例⽽已,所以 Flink 也是⼀款真正的流批统⼀的计算引擎。

 

Flink当前整体架构介绍

image.png

Flink API 最底层的抽象为有状态实时流处理。其抽象实现是 Process Function,并且 Process Function 被 Flink 框架集成到了 DataStream API 中来为我们使用。它允许用户在应用程序中自由地处理来自单流或多流的事件(数据),并提供具有全局一致性和容错保障的状态。此外,用户可以在此层抽象中注册事件时间(event time)和处理时间(processing time)回调方法,从而允许程序可以实现复杂计算。

Flink API 第二层抽象是 Core APIs。其中包含 DataStream API(应用于有界/无界数据流场景)和 DataSet API(应用于有界数据集场景)两部分。Core APIs 提供的流式 API(Fluent API)为数据处理提供了通用的模块组件,例如各种形式的用户自定义转换(transformations)、联接(joins)、聚合(aggregations)、窗口(windows)和状态(state)操作等。此层 API 中处理的数据类型在每种编程语言中都有其对应的类。

Flink API 第三层抽象是 Table APITable API 是以表(Table)为中心的声明式编程API,例如在流式数据场景下,它可以表示一张正在动态改变的表。Table API 遵循(扩展)关系模型:即表拥有 schema(类似于关系型数据库中的 schema),并且 Table API 也提供了类似于关系模型中的操作,比如 select、project、join、group-by 和 aggregate 等。Table API 程序是以声明的方式定义应执行的逻辑操作,而不是确切地指定程序应该执行的代码。尽管 Table API 使用起来很简洁并且可以由各种类型的用户自定义函数扩展功能,但还是比 Core API 的表达能力差。此外,Table API 程序在执行之前还会使用优化器中的优化规则对用户编写的表达式进行优化。表和 DataStream/DataSet 可以进行无缝切换,Flink 允许用户在编写应用程序时将 Table API 与 DataStream/DataSet API 混合使用。

Flink API 最顶层抽象是 SQL。这层抽象在语义和程序表达式上都类似于 Table API,但是其程序实现都是 SQL 查询表达式。SQL 抽象与 Table API 抽象之间的关联是非常紧密的,并且 SQL 查询语句可以在 Table API 中定义的表上执行。

  image.png

SDK 层:SQL、Table DataSteam(定时触发)、 pyFlink(ML)

执行引擎层(Runtime 层):执行引擎层提供了统一的 DAG,用来描述数据处理的 Pipeline,不管是流还是批,都会转化为 DAG 图,调度层再把 DAG 转化成分布式环境下的 Task,Task通过Shuffle Service做数据交换

状态存储层:State Backend负责存储算子的状态信息

image.png JobManager(JM)负责整个任务的协调工作,包括:调度 task、触发协调 Task 做 Checkpoint、协调容错恢复等,核心有下面三个组件:

Dispatcher: 接收作业,拉起 JobManager 来执行作业,并在 JobMaster 挂掉之后恢复作业;

JobMaster: 管理一个 job 的整个生命周期,会向 ResourceManager 申请 slot,并将 task 调度到对应 TM 上;

ResourceManager:负责 slot 资源的管理和调度,Task manager 拉起之后会向 RM 注册;

 

TaskManager(TM):负责执行一个 DataFlow Graph 的各个 task 以及 data streams 的 buffer 和数据交换。

Flink 作业示例

image.png

image.png 在flink中有四层执行图,StreamGraph -> JobGraph -> ExecutionGraph -> 物理执行图,如图所示:

  20201219105133501.png

StreamGraph:是根据用户通过 Stream API 编写的代码生成的最初的图,用来表示程序的拓扑结构。每个转换操作会生成一个StreamNode,两个StreamNodes之间由StreamEdge连接在一起,StreamEdge表示的是算子操作之间的数据传递逻辑,整个图直观表现就是各个算子连接在一起形成的DAG。

JobGraph:StreamGraph经过优化后生成了 JobGraph,提交给 JobManager 的数据结构。在一步做了一个优化,就是将多个符合条件的StreamNode节点 chain 在一起作为一个JobVertex节点,这样可以减少数据在节点之间流动所需要的序列化、反序列化、传输消耗。JobGraph在Client端生成。

ExecutionGraph:JobManager 根据 JobGraph 生成ExecutionGraph。ExecutionGraph是JobGraph的并行化版本:一个JobVertex对应一个ExecutionJobVertex,根据一个JobVertex的并行度(一个task可以并行在不同的TaskManager上执行),生成相对应数量的ExecutionVertex。同时在这个图中多了一层IntermediateResult,表示执行的中间结果。IntermediateResult与ExecutionJobVertex之间通过ExecutionEdge形成连接。ExecutionGraph是调度层最核心的数据结构,JobManager通过它来调度任务的执行。

物理执行图:JobManager 根据 ExecutionGraph 对 Job 进行调度后,在各个TaskManager 上部署 Task 后形成的物理执行计划,与ExecutionGraph基本保持一致。它只是一个任务执行状态的逻辑展示,并不是一个具体的数据结构。

image.png Operator chain算子链减少了数据的序列化和数据传输的消耗。不过不是所有的算子之间都是可以进行chain的,只有当下游算子的子任务只依赖了上游算子的一个子任务的时候,才能做算子链优化(与spark中的窄依赖同理)。

image.png

一个task slot指代了TaskManager分配给一个任务执行的资源(主要是内存资源,cpu没有做隔离)。虽然每个task slot拥有自己独享的内存资源,但是在一个TaskManager上的所有任务共享TCP连接和心跳消息,以节省资源。

image.png

参考文献

[(34条消息) flink学习(四)——flink任务执行原理详解_Yohohaha的博客-CSDN博客_flink任务](url)

juejin.cn/post/712275…