流/批/OLAP 一体的 Flink 引擎介绍 | 青训营笔记

122 阅读6分钟

流/批/OLAP 一体的 Flink 引擎介绍 | 青训营笔记

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

重点内容:

一、Flink概述

1、为什么需要流式计算?

大数据的实时性带来价值更大,比如:

  • 监控场景:如果能实时发现业务系统的健康状态

  • 实时推荐:比如在抖音,如果可以根据用户的行为数据发掘用户的兴趣、偏好,就能向用户推荐更感兴趣的内容

  • 金融风控:如果实时监测出异常交易的行为,就能及时阻断风险的发生

2、Flink为什么能脱颖而出

流式计算框架对比:
StormSpark StreamingFlink
Streaming ModelNativemini-batchNative
一致性保证At Least/Most OnceExactly-OnceExactly-Once(精确一次的计算语义)
SEE低延迟(毫秒级)延迟较高(秒级)低延迟(毫秒级)
吞吐LowHighHigh
容错ACKRDD Based CheckpointCheckpoint ( Chandy-Lamport)
StateFulNoYes ( DStream )Yes (Operator)
SQL支持NoYesYes

Flink的特点:

  • 精确一次的计算语义

  • 状态容错

  • Dataflow编程模型、windows等高阶需求支持友好

  • 流批一体

二、Flink整体架构

1、Flink分层架构

图一: image.png

  1. SDK层:目前主要有三类SQL/Table、DataStream、Python

  2. 执行引擎层(Runtime层):Runtime层提供统一的DAG,用来描述数据处理的流水线,不管是流还是批,都会转换为DAG图,调度层再把DAG转换成分布式环境下的Task,Task之间通过Shuffle传输数据

  3. 状态存储层:负责存储算子的状态信息

  4. 资源调度层:目前Flink可以指出部署在多种环境

2、Flink整体架构

一个Flink集群,主要包含以下两个核心组件

1、JobManager (JM):协调 Flink 应用程序的分布式执行。它决定何时调度下一个 task(或一组 task)、对完成的 task 或执行失败做出反应、协调 checkpoint、并且协调从失败中恢复等等。这个进程由三个不同的组件组成:

  1. Dispatcher:接受作业,拉起JobManager来执行作业,并在JobMaster挂掉之后恢复作业。
  • JobMaster:管理一个job的整个生命周期,会向ResourceManager申请slot,并将task调度到对应TM上。
  • ResourceManage:负责slot资源的管理和调度,Task manager拉起之后会向RM注册。

2、TaskManager (TM):执行作业流的 task,并且缓存和交换数据流。在TaskManager中资源调度的最小单位是 task slot。TaskManager 中 task slot 的数量表示并发处理 task 的数量。一个 Slot只能运行同一个task的subTask

图二: image.png

3、Flink如何做到流批一体
(一)做到流批一体相比于单独使用批流两套系统的优点:
  • 1.做到流批一体人力成本比较低,而使用批、流两套系统,相同逻辑需要开发两遍

  • 2.单独使用批流两套系统会导致数据链路冗余--本身计算内容是一致的,由于是两套链路,相同逻辑需要运行两遍,产生一定的资源浪费,而流批一体可以很好的解决这个问题

  • 3.单独使用批流两套系统会导致据口径不一致--两套系统、两套算子、两套UDF,通常会产生不同程度的误差,这些误差会给业务方带来非常大的困扰,使用流批一体可以很好的解决业务方的困扰

(二)为什么可以做到流批一体

站在Flink的角度,Everything is Streams,无边界数据集是一种数据流,一个无边界的数据流可以按时间切段成一个个有边界的数据集,所以有界数据集(批式数据)也是一种数据流。

因此,不管是有边界的数据集(批式数据)还是无边界数据集,Flink都可以天然地支持,这是 Flink支持流批一体的基础。并且Flink在流批一体上,从上面的API到底层的处理机制都是统一的,是真正意义上的流批一体。

主要从下面几个模块进行流批一体:

  1. SQL层

  2. DataSteam API层统一,批和流都可以使用DataSteam API开发

  3. Schedler层架构统一,支持流批场景(主要负责将作业的DAG转化为在分布式环境中可以执行的Task)

在Flink1.12版本前,支持两种调度模式:

模式特点场景
EAGER申请一个作业所需的所有资源,同时调度这个作业的所有task,task之间采用pipeline通信Stream作业场景
LAZY先调度上游,等待上游产生护具或结束后再调度下游,类似Spark的STAGE执行模式Batch作业场景
  1. Failover Recovery层架构统一,支持流批场景

  2. Shuffle Service层架构统一,根据不同场景选择不同服务

实际上,分布式计算中所有涉及到上下游衔接的过程,都可以理解为Shuffle.

针对不同的分布式计算框架,Shufle通常有几种不同的实现:

1、基于文件的Pull Based Shuffle.具有较高容错性,适合大规模批处理作业,容错性更好。比如spark或MR。

2、基于Pipeline的Push Based Shuffle,具有低延时高性能,比如Flink,Storm。

流和批Shuffle之间的差异:

1、Shuffle的生命周期:流作业Shuffle数据与Task绑定,批作业和Shuffle是解耦的

2、Shuffle数据存储介质:流作业的Shuffle存储在内存,批作业的Shuffle存储在磁盘

3、Shuffle的部署方式:流作业的Shuffle服务和计算节点部署在一起,可以减少网络开销,从而减少延迟,批作业不同

在Streaming和OLAP场景:

  • 为了性能的需要,通常会使用基于Pipeline的Shuffle模式

在Batch场景

  • 一般会选取Blocking的 Shuffle模式

为了统一Flink在 Streaming和 Batch模式下的Shuffle架构,Flink 实现了一个 Pluggable的 ShuffleService框架,抽象出一些公共模块。

三、Flink架构优化

三种场景对比:

流式计算批式计算交互式分析(OLAP)
SQLYesYesYes
实时性高、处理延退毫秒级别高、查询延退在秒级但要求高并发查询
容错能力中,大作业失败重跑代价高没有,失败重试即可
状态YesNoNo
准确性Exactly Once 要求高,重跑需要恢复之前的状态Exactly Once 失败重跑即可Exactly Once 失败重跑即可
扩展性YesYesYes

通过前面的分析,可以发现:

  • 1.批式计算是流式计算的特例,Everything is Streams,有界数据集(批式数据)也是一种数据流、 一种特殊的数据流

  • 2.而OLAP计算是一种特殊的批式计算,它对并发和实时性要求更高,其他情况与普通批式作业没 有特别大区别。

所以Flink可以做到流/批/OLAP 一体的

注:

图片来源

图一:青训营

图二:Flink Architecture |Apache Flink