流批OLAP一体的Flink | 青训营笔记

128 阅读8分钟

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

一、flink概述

Flink 起源于 Stratosphere 项目,Stratosphere 是在 2010~2014 年由 3 所地处柏林的大学和欧洲的一些其他的大学共同进行的研究项目,2014 年 4 月 Stratosphere 的代码被复制并捐赠给了 Apache 软件基 金会, 参加 这个孵化项目的初始成员是Stratosphere 系统的核心开发人员,2014 年 12 月,Flink 一跃成为 Apache 软件基金会的顶级项目。

在德语中,Flink 一词表示快速和灵巧,项目采用一只松鼠的彩色图案作为 logo,这不仅是因为松鼠具有快速和灵巧的特点,还因为柏林的松鼠有一种迷人的红棕色,而 Flink 的松鼠 logo 拥有可爱的尾巴,尾巴的颜色与 Apache 软件基金会的 logo 颜色相呼应,也就是说,这是一只 Apache 风格的松鼠。

image.png

Flink 主页在其顶部展示了该项目的理念:“Apache Flink 是为分布式、高性能、随时可用以及准确的流处理应用程序打造的开源流处理框架”。

Flink流计算

  • 实时计算的业务场景需求、为什么会出现流式计算

    • 数据实时价值更大;
    • 大数据批式处理分钟级、小时级、天极,部分业务场景无法接受;
  • 流式计算特点:

    • 实时计算、快速、低延迟;
    • 无限流、动态、无边界;
    • 7*24 持续运行;

二、Flink架构

1、Flink分层架构

Flink分层框架图如上,从上到下分别有SDK层、执行引擎层、状态存储层、资源调度层。

  • SDK层:有三类,SQL/Table、DateStream、pyFlink。分别对应sql语句、java和scala、python。
  • 执行引擎层(Runtime层):执行引擎层提供了统一的 DAG,用来描述数据处理的 Pipeline,不管是流还是批,都会转化为DAG图,调度层再把 DAG转化成分布式环境下的Task,Task 之间通过Shuffle传输数据;
  • 状态存储层:存储算子的状态信息。
  • 资源调度层:支持部署多种环境如 主流的yarn

image.png

上图为 Flink 技术栈的核心组成部分,Flink分别提供了面向流式处理的接口(DataStream API)和面向批处理的接口(DataSet API) 。因此,Flink既可以完成流处理,也可以完成批处理。 Flink 支持的拓展库涉及机器学习(FlinkML)、复杂事件处理(CEP)、以及图计算(Gelly),还有分别针对流处理和批处理的 Table API。能被 Flink Runtime 执行引擎接受的程序很强大,但是这样的程序有着冗长的代码,编写起来也很费力,基于这个原因,Flink 提供了封装在 Runtime 执行引擎之上的 API, 以帮助用户方便地生成流式计算程序。 Flink提供了用于流处理的DataStream API和用于批处理的DataSet API。尽管Flink Runtime执行引擎是基于流处理的,但是 DataSet API 先于 DataStream API 被开发出来,这是因为工业界对无限流处理的需求在 Flink 诞生之初并不大。DataStream API 可以流畅地分析无限数据流,并且可以用 Java 或者 Scala 来实现。开发人员需要基于一个叫 DataStream 的数据结构来开发,这个数据结构用于表示永不停止的分布式数据流。

Flink的分布式特点体现在它能够在成百上千台机器上运行,它将大型的计算任务分成许多小的部分,每个机器执行一部分。Flink 能够自动地确保发生机器故障或者其他错误时计算能够持续进行,或者在修复 bug 或进行版本升级后有计划地再执行一次。这种能力使得开发人员不需要担心运行失败。Flink 本质上使用容错性数据流,这使得开发人员可以分析持续生成且永远不结束的数据(即流处理)。

2、Flink总体架构

JobManagerTaskManager

JobManager处理器: 也称之为 Master,用于协调分布式执行,它们用来调度 task,协调检查点,协调失败时恢复等。Flink 运行时至少存在一个 master 处理器,如果配置高可用模式则会存在多个 master 处理器,它们其中有一个是 leader,而其他的都是 standby。

TaskManager处理器: 也称之为 Worker,用于执行一个 dataflow 的 task(或者特殊的 subtask)、数据缓冲和 data stream 的交换,Flink 运行时至少会存在一个 worker处理器。

JM 核心有下面三个组件:

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

3、Flink作业流程

  • ExecutionGraph 生成:DataStream API Code --> JobGraph --> ExecutionGraph(Parallelized)

    • 业务逻辑代码转换为一个 Streaming DataFlow Graph
    • 紧接着会将上面的Streaming DataFlow Graph转化 Parallel Dataflow (内部叫Execution Graph) :由规定规模的算子并发执行
    • 为了更高效地分布式执行,Flink 会尽可能地将不同的operator链接(chain)在一起形成Task。 这样每个Task 可以在一个线程中执行,内部叫做OperatorChain。
    • 最后将上面的Task调度到具体的TaskManager中的slot中执行,一个Slot只能运行同一个task的subTask

4、Flink如何流批一体

由于寻常处理数据时实时数仓和离线数仓会根据不同的方案采用不同的计算引擎,像实时数仓大多会选择flink,离线数仓会选择hive和spark。那么如果处理相同的业务逻辑就会有很大的痛点。

1、人力成本比较高:批、流两套系统,相同逻辑需要开发两遍; 2.数据链路冗余:本身计算内容是一致的,由于是两套链路,相同逻辑需要运行两遍,产生一 定的资源浪费; 3.数据口径不一致:两套系统、两套算子、两套UDF,通常会产生不同程度的误差,这些误差 会给业务方带来非常大的困扰。

其实可以把批式计算看做流计算的特例,即有界数据流是一种特殊的无界数据流。站在 Flink 的角度,Everything is Streams,一个无边界的数据流可以按时间切段成一个个有边界的数据集。因此,不管是有边界的数据集(批式数据)还是无边界数据集,Flink 都可以天然地支持,这是 Flink 支持流批一体的基础。并且 Flink 在流批一体上,从上面的 API 到底层的处理机制都是统一的,是真正意义上的流批一体。

Flink 具体如何做到流批一体

  • SQL 层;
  • DataStream API 层统一,批和流都可以使用 DataStream API 来开发;
  • Scheduler 层架构统一,支持流批场景;
  • Failover Recovery 层架构统一,支持流批场景;
  • Shuffle Service 层架构统一,流批场景选择不同的 Shuffle Service;

三、Flink架构优化

1.流批OLAP业务场景

img

img

2.Flink 做 OLAP 的优势

  • 统一引擎:流处理、批处理、OLAP 统一使用 Flink 引擎;

    • 降低学习成本,仅需要学习一个引擎;
    • 提高开发效率,很多 SQL 是流批通用;
    • 提高维护效率,可以更集中维护好一个引擎;
  • 既有优势:利用 Flink 已有的很多特性,使 OLAP 使用场景更为广泛;

    • 使用流处理的内存计算、Pipeline;
    • 支持代码动态生成;
    • 也可以支持批处理数据落盘能力;
  • 相互增强:OLAP 能享有现有引擎的优势,同时也能增强引擎能力

    • 无统计信息场景的优化;
    • 开发更高效的算子;
    • 使 Flink 同时兼备流、批、OLAP 处理的能力,成为更通用的框架。

3.Flink 在 OLAP 架构上的问题与设想

  • 架构与功能模块:

    • JobManager 与 ResourceManager 在一个进程内启动,无法对JobManager 进行水平扩展;
    • Gateway 与 Flink Session Cluster 互相独立,无法进行统一管理;
  • 作业管理及部署模块:

    • JobManager 处理和调度作业时,负责的功能比较多,导致单作业处理时间长、并占用了过多的内存;
    • TaskManager 部署计算任务时,任务初始化部分耗时验证,消耗大量 CPU;
  • 资源管理及计算任务调度:

    • 资源申请及资源释放流程链路过长;
    • Slot 作为资源管理单元,JM 管理 slot 资源,导致 JM 无法感知到 TM 维度的资源分布,使得资源管理完全依赖于 ResourceManager;
  • 其他:

    • 作业心跳与 Failover 机制,并不合适 AP 这种秒级或毫秒级计算场景;
    • AP 目前使用 Batch 算子进行计算,这些算子初始化比较耗时;