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

84 阅读7分钟

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

流/批/OLAP一体的Flink计算引擎介绍

一. Flink概述

1.1 Apache Flink的诞生背景

大数据(Big Data):指无法在一定时间内用常规软件工具对其进行获取、存储、管理和处理的数据集合。

  • 海量化
  • 多样化
  • 快速化
  • 价值化

大数据计算架构的发展历史:

  • 史前阶段~2006
    • 传统数仓
    • Oracle
    • 单机
    • 黑箱使用
  • Hadoop
    • 分布式
    • Map-Reduce
    • 离线计算
  • Spark
    • 批处理
    • 流处理
    • SQL高阶API
    • 内存迭代计算
  • Flink
    • 流计算
    • 实时、更快
    • 流批一体
    • Streaming/Batch SQL

1.2 Flink为什么脱颖而出

流式计算框架对比: image.png

二. Flink整体框架

2.1 Flink分层框架

image.png

  1. SDK层:Flink的三类SDK,SQL/Table、DataStream(Java)、pyFlink(Python)
  2. 执行引擎层(Runtime层):提供了统一的DAG,用来描述数据处理的pipeline不管是流还是批,都会转化为DAG图调度层(Scheduler) 再把DAG转化成分布式环境下的Task,Task之间通过 Shuffle 传输数据;
  3. 状态存储层:负责存储算子的状态信息;
  4. 资源调度层:目前Flink支持部署多种环境(Yarn,K8s)

2.2 Flink总体架构

image.png 一个Flink集群,主要包含以下两个核心部件:

  • JobManager(JM):负责整个任务的协调工作
    • 调度task
    • 出发协调task做Checkpoint
    • 协调容错恢复等
  • TaskManager(TM):负责执行一个DataFlow Graph的各个task以及data streams的buffer和数据交换

2.2.1 JobManager职责

image.png

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

2.3 Flink作业示例(WordCount)

从Kafka中读取一个实时数据流,每10s统计一次单词出现次数,DataStream实现代码如下: image.png

  • 业务逻辑转换为一个Streaming DataFlow Graph(即DAG,有向无环图) image.png
  • 假设sink算子的并发为1,其余算子并发为2,上面的Streaming DataFlow Graph转为Parallel DataFlow(内部叫Execution Graph) image.png
  • Flink会进行operation chain,将一些算子链接形成一个一个Task,这样每个Task可以在一个线程里执行,减少切换线程的工序。
    • 如上图中Source1对map1直接进行数据传输,one2one,这样可以将他们放在一起,变成顺序执行;
    • 而map到下一步的window是不确定的,因为要通过keyBy()的哈希进行确定属于哪一个window image.png
  • 最后将上面的task调度到具体的TM中的slot中执行,一个slot只能运行同一个Task的subTask。
    • slot是单独的threads执行,内存未严格隔离 image.png

2.4 Flink如何做到流批一体化

2.4.1 为什么要流批一体化

流和批业务的特点: image.png 批式计算相对于流式计算核心的区别: image.png 若是不流批一体化,对于同一应用(如抖音)的不同业务场景(流业务,批业务)需要构建两套系统: image.png image.png 上述架构通点:

  • 人力成本高:批、流两套系统,相同逻辑需要开发两遍;
  • 数据链路冗余:本身计算内容一致,但两条链路,同样的逻辑要运算两遍,产生一定的资源浪费;
  • 数据口径不一致:两套系统产生不同程度的误差;

2.4.2 Flink如何做到流批一体化

image.png 批计算是流计算的特例,Everything is Streams,有界数据(批式数据)也是一种(特殊的)数据流,一个无边界数据流可以按照时间(如1s)切段成一个个有边界的数据集。

这是Flink支持流批一体的基础,可以用一套引擎解决两种场景,对不同场景支持不同扩展性、实现不同优化策略。并且Flink在流批一体的基础上,从上面的API到底层的处理机制都是统一的,是真正意义上的流批一体

Flink通过以下模块来做流批一体:

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

2.4.3 流批一体的Scheduler层

主要负责将作业的DAG转化为在分布式环境中可执行的task image.png

Flink1.12以前的版本中,支持以下两种调度方式:

  • EAGER模式:申请一个作业所需要的全部资源,然后同时调度这个作业的全部Task,所有Task之间采取pipeline进行通信 (Stream作业场景)

    • 需要所有task所需的资源全部调度才能进行
  • LAZY模式:先调度上游,等待上游产生数据或结束后再调度下游,类似Spark的Stage (Batch作业场景)

    • 最小调度一个task即可,集群拥有1个slot就能运行

由Pipeline的数据交换方式连接的Task构成为一个 Pipeline Region ,本质上流批作业都按照 pipeline region粒度 来申请资源和调度任务

image.png

  • ALL_ENDGES_BLOCKING:(批处理)所有Task之间的数据交换都是BLOCKING模式,数据非实时传输,需要落盘(写到disk或数据库里) (12个Pipeline Region)

  • ALL_EDGES_PIPELINED:(流处理)所有Task都是pipeline模式,数据产出全部直接发给下游,不做落盘(直接传输) (1个Pipeline Region)

2.4.4 流批一体的Shuffle Service层

  • shuffle:在分布式计算中,用来连接上下游数据交互的过程。 实际上,分布式计算中所有涉及到上下游衔接的过程,都可以理解为shuffle。

  • shuffle的不同实现:

    • 基于文件的Pull Based Shuffle
      • 有较高的容错性和稳定性,适合大规模的批处理作业
    • 基于Pipeline的Push Based Shuffle
      • 低延迟和高性能,但是shuffle数据没有保存下来,如果是batch任务的话,就需要进行重跑恢复
  • 流和批shuffle之间的差异:

    • 数据的生命周期:流shuffle数据与task绑定,批shuffle数据与task解耦
    • 据存储介质:流生命周期短,为实时性经常存储在内存;批数据量大容错高,存储磁盘
    • 部署方式:流服务计算节点部署在一起,节省网络开销,减少latency;批作业不同
  • Flink对流和批提供 streamingbatch 两种类型的shuffle

    • 在streaming/OLAP场景:为了性能,通常使用基于Pipeline的Shuffle模式

    • 在batch场景:Blocking的shuffle模式

      为了统一在这两种模式下的shuffle架构,Flink实现了一个Pluggable的Shuffle Service框架,抽象出一些公共模块
      
  • Shuffle Service

    • Netty shuffle service:既支持pipeline也支持blocking,Flink默认的Shuffle Service策略
    • Remote shuffle service:既支持pipeline也支持blocking,不过pipeline会性能下降,主要用在batch的blocking场景

三. Flink架构优化

3.1 流/批/OLAP业务场景对比

image.png image.png

3.2 为什么三种业务场景可以用一套引擎解决

image.png 批是流的特例,OLAP是批的特例,对并发和实时性要求更高,其他情况与批没有区别 image.png

3.3 Flink如何支持OLAP

  • Flink做OLAP的优势

    • 引擎统一:降低学习成本提高开发与维护效率
    • 既有优势:内存计算、code-gen、pipeline shuffle、session
    • 生态支持:跨数据源查询支持、TCP-DS基准测试性能强
  • OLAP场景的挑战

    • 秒级、毫秒级小作业:并行性高
    • 作业频繁启停,资源碎片:磁盘开销
    • Latency+QPS要求
  • OLAP架构现状 image.png

    • Client:提交SQL Query;
    • Gateway:接受Client提交的SQL Query,对SQL进行语法解析和查询优化,生成Flink作业执行计划,提交给Session集群;
    • Session Cluster:执行作业调度及计算并返回结果
  • Flink在OLAP架构的问题和设想

    • 功能与架构模块:
      • JobManager与ResourceManager在一个进程内启动,无法对JobManager进行扩展
      • Gateway与Flink Session Cluster相互独立,无法统一进行管理 (SQL解析优化管理)
    • 作业管理与部署模块:
      • JobManager处理调度作业时负责功能多,但作业处理时间长,占用过多内存;(高并发占用过多)
      • TaskManager部署计算任务时,初始化部分耗时严重,消耗大量CPU;
    • 资源管理及计算任务调度:
      • 资源申请/释放流程链路长
      • slot作为资源管理单位,JM管理slot导致JM无法感知TM的资源分布,使得资源管理完全依赖于ResourceManager
    • 其他:
      • 作业心跳/failover机制不适合AP的秒级毫秒级计算
      • AP使用Batch算子计算,初始化比较耗时