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

293 阅读8分钟

Apache Flink 概述

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

批处理

所谓 批处理 是指把一项数据处理任务先分解成更小粒度的任务,把这些任务分布在集群中的各台实例上进行计算,之后把各实例上的计算结果重新计算和组合成最终结果。批处理系统通常会操作大量的静态的数据,并等到这些数据全部处理完成后才能得到返回的结果。

批处理方式使用的数据集通常有以下特征:

  • 有界:批处理数据集代表数据的有限集合
  • 持久:数据通常始终存储在某种类型的持久存储位置中
  • 大量:批处理操作通常是处理极为海量数据集的唯一方法

流处理

流处理 方式会随时对进入系统的数据进行实时的计算,这种模式不需要针对整个数据集执行操作,而是对通过系统传输的每个数据项执行操作。流处理中的数据集是 无边界 的,这就产生了几个重要的影响:

  • 完整数据集只能代表截至目前已经进入到系统中的数据总量。
  • 工作数据集也许更相关,在特定时间只能代表某个单一数据项。
  • 处理工作是基于事件的,除非明确停止否则没有“尽头”。处理结果立刻可用,并会随着新数据的抵达继续更新。

混合处理

在大数据处理技术中流派中,除了单纯的批处理和流处理模式之外,还有一些处理框架既可以进行批处理也可以进行流处理,我们称之为混合处理框架。虽然专注于一种处理方式可能非常适合特定场景,但是混合框架为数据处理提供了通用的解决方案。这些框架可以用相同或相关的组件和 API 处理两种类型的数据,借此让不同的处理需求得以简化。混合处理框架中目前比较著名的就是 Spark 和 Flink 。

为什么 Flink 会脱颖而出

完全一次保证:故障后应正确恢复有状态运算符中的状态;

低延迟:越低越好。许多应用程序需要亚秒级延迟;

高吞吐量:随着数据速率的增长,通过管道推送大量数据至关重要;

强大的计算模型:框架应该提供一种编程模型,该模型不限制用户并允许各种各样的应用程序在没有故障的情况下,容错机制的开销很低;

流量控制:来自慢速算子的反压应该由系统和数据源自然吸收,以避免因消费者缓慢而导致崩溃或降低性能;

乱序数据的支持:支持由于其他原因导致的数据乱序达到、延迟到达后,计算出正确的结果;

完备的流式语义:支持窗口等现代流式处理语义抽象;

Google Dataflow Model 的开源引擎实现。

Apache Flink 开源生态

Apache Flink 在开源生态上的能力比较强大,可以支持:

流批一体:支持流式计算和批式计算;

OLAP:Flink 可以支持 OLAP 这种短查询场景;

Flink ML:pyFlink、ALink、AIFlow 等生态支持 Flink 在 ML 场景的应用;

Gelly:图计算;

Stateful Function:支持有状态的 FAAS 场景;

Flink 整体架构

Flink 分层架构

Flink 整体架构

  • 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 如何做到流批一体

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

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

Apache Flink 主要从以下几个模块来做流批一体:

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

Flink 架构优化

Flink 如何支持 OLAP 场景

Flink 做 OLAP 的优势

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

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

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

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

Flink OLAP 场景的挑战

  • 秒级和毫秒级的小作业;

  • 作业频繁启停、资源碎片;

    • Flink OLAP 计算相比流式和批式计算,最大的特点是 Flink OLAP 计算是一个面向秒级和毫秒级的小作业,作业在启动过程中会频繁申请内存、网络以及磁盘资源,导致 Flink 集群内产生大量的资源碎片;
  • Latency + 高 APS 要求;

    • OLAP 最大的特点是查询作业对 Latency 和 QPS 有要求的,需要保证作业在 Latency 的前提下提供比较高的并发调度和执行能力,这就对 Flink 引擎提出了一个新的要求。
  • Flink OLAP 架构现状

    • Client:提交 SQL Query;

    • Gateway:接收 Client 提交的 SQL Query,对 SQL 进行语法解析和查询优化,生成 Flink 作业执行计划,提交给 Session 集群;

    • Session Cluster:执行作业调度及计算,并返回结果。

      • JobManager 管理作业的执行,在接收到 Gateway 提交过来的作业逻辑执行计划后,将逻辑执行计划转换为物理执行计划,为每个物理计算任务分配资源,将每个计算任务分发给不同的 TaskManager 执行,同时管理作业以及每个计算任务执行状态;
      • TaskManager执行具体的计算任务,采用线程模型,为每个计算任务创建计算线程,根据计算任务的上下游数据依赖关系跟上游计算任务建立/复用网络连接,向上游计算任务发送数据请求,并处理上游分发给它的数据。

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

  • 架构与功能模块:

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

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

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

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