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

116 阅读9分钟

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

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


一、Flink概述

1.1 Apache Flink 诞生的背景

随着大数据时代的到来,众多处理大数据的技术不断推出。而直到Hadoop框架的诞生,分布式计算成为大数据处理的主要手段。Hadoop的计算框架MapReduce作为初代计算引擎,它的最大价值在于提供一种分布式计算的核心思想,map和reduce,但随着业务中海量的无限流数据集越来越普遍,使用作为无限流数据流处理而设计的系统处理数据的场景就越多,MapReduce的局限性就体现出来了。所以Apache Flink诞生了。

Apache Flink是为分布式、高性能、随时可用以及准确的的处理流处理应用程序打造的开源流处理框架。

1.2 为什么 Apache Flink会脱颖而出

对比四种主流的计算引擎

  • MapReduce:批处理引擎,为其他计算引擎提供了大数据处理的核心思想,即map和reduce

  • storm:流式计算引擎,但是Storm API的low-level以及开发效率低下。一致性问题:storm更多考虑到实时流计算的处理延时而非数据的一致性保证。

  • Spark:集流式处理和批处理于一身的统一的计算引擎,基于内存计算,提高了性能。SparkStreaming作为Spark流式处理的一个组件,SparkStreaming相比于Storm的低阶API以及无法正确性语义保证,Spark是流处理的分水岭:第一个广泛使用的大规模流处理引擎,既提供较为高阶的API抽象,同时提供流式处理正确性保证。

  • Flink:集流式处理和批处理于一身的统一的计算引擎,吸收了以上3个框架的优点并改进后的计算框架,它还具备很多其他框架没有的技术特征:

    • 完全一次保证:故障后应正确恢复有状态运算符中的状态;
    • 低延迟:越低越好。许多应用程序需要亚秒级延迟;
    • 高吞吐量:随着数据速率的增长,通过管道推动大量数据直关重要;
    • 强大的计算模型:框架应该提供一种编程模型,该模型不限制用户并允许各种各样的应用程序在没有故障的情况下,容错机制的开销很低;
    • 流量控制:来自慢速算子的反压应该由系统和数据源自然吸收,以避免因消费者缓慢而导致崩溃或降低性能;
    • 乱序数据的支持:支持由于其他原因导致的数据乱序达到、延迟到达后,计算出正确的结果;
    • 完备的流式语义:支持窗口等现代流式处理语义抽象。

二、Apache Flink的整体架构

2.1 Flink的分层架构

  1. SDK层:Flink 的 SDK 目前主要由有三类

    • SQL/Table:提供SQL语法对数据进行处理
    • DataStream:实际中我们有很多业务无法直接使用SQL来完成,这就需要我们使用DataStream API 用Java编程实现需求
    • Python:主要为pyFlink,和 Flink ML提供基础
  2. 执行引擎层(Runtime 层) :执行引擎层提供了统一的DAG,用来描述数据处理的 Pipeline,不管是流还是批,都会转化为DAG图,调度层再把DAG转换成分布式环境下的Task,Task之间通过Shuffle传输数据;

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

  4. 资源调度层:目前Flink可以支持在多种环境(Standalone,yarn,K8S等)

2.2 Flink的总体架构

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

  1. JobManager(JM) :负责整个任务的协调工作,包括:调度Task、触发协调Task做Checkpoint、协调容错恢复等。

    JobManager的职责:

    image-20220726214033950.png Dispatcher:接收作业,拉起JobManager来执行作业,并在JobMaster挂掉后恢复作业

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

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

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

image-20220726212958464.png 图片源于:Flink Architecture

2.3 Flink作业示例

流式的WordCount示例,从kafka中读取一个实时数据流,每10秒统计一次单词出现的次数,DataStream实现代码如下:

// Source
DataStream<String> lines = env.addSource(new FlinkKafkaConsumer<>(...));
DataStream<Event> events = lines.map((line)->parse(line));
// transformation
DataStream<Statistics> stats = events.keyBy(event -> event.id)
    .timeWindow(Time.second(10))
    .apply(new MyWindowAggregationFunction());
// sink
stats.addSink(new BucketingSink(path));

2.4 Flink如何做到流批一体

为什么需要流批一体

一些业务场景,除了实时的数据统计需求,为了确认运营或产品的效果,用户同时还需要和历史数据做比较,比如,抖音一些直播数据的统计;

这种架构有一些痛点:

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

Flink如何做到流批一体

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

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

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

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

流批一体的 Scheduler 层

  • Scheduler 主要负责将作业的 DAG 转化为在分布式环境中可以执行的 Task

  • 1.12 之前的 Flink 版本,Flink 支持两种调度模式:

    • EAGER(Streaming 场景) :申请一个作业所需要的全部资源,然后同时调度这个作业的全部 Task,所有的 Task 之间采取 Pipeline 的方式进行通信;
    • LAZY(Batch 场景) :先调度上游,等待上游产生数据或结束后再调度下游,类似 Spark 的 Stage 执行模式。
  • Pipeline Region Scheduler 机制:由Pipeline的数据交换方式连接的Task构成为一个Pipeline Region,本质上,不管是流作业还是批作业,都是按照Pipeline Region粒度来申请资源和调度任务。

流批一体的 Shuffle Service 层

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

    • 基于文件的Pull Based Shuffle:数据落入磁盘
    • 基于Pipeline的Push Based Shuffle:数据存在内存
  • 流和批 Shuffle 之间的差异:

    • Shuffle 数据的生命周期:流作业的 Shuffle 数据与 Task 是绑定的,而批作业的 Shuffle 数据与 Task 是解耦的
    • Shuffle 数据存储介质:流作业的生命周期比较短、而且流作业为了实时性,Shuffle 通常存储在内存中,批作业因为数据量比较大以及容错的需求,一般会存储在磁盘里
    • Shuffle 的部署方式:流作业 Shuffle 服务和计算节点部署在一起,可以减少网络开销,从而减少 latency,而批作业则不同

三、Flink 架构优化

  • Flink 做 OLAP 的优势

    • 统一引擎:流处理、批处理、OLAP 统一使用 Flink 引擎
    • 既有优势:利用 Flink 已有的很多特性,使 OLAP 使用场景更为广泛
    • 相互增强:OLAP 能享有现有引擎的优势,同时也能增强引擎能力
  • Flink OLAP 场景的挑战

    • 秒级和毫秒级的小作业
    • 作业频繁启停、资源碎片
  • Flink OLAP 架构现状

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

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

四、个人总结与思考

Flink是集流处理、批处理、OLAP于一体的计算引擎,在至今的大数据处理领域占据重要的地。Flink

在流处理和批处理领域做的更好,那么作为Flink是否会彻底的取代Spark框架呢?Flink在未来会不会实现流处理和批处理无缝切换、界限越来越模糊呢?而现在Flink已经开始支持Python语言进行开发,那么未来会不会支持更多的语言进行开发呢?比如:C++、GO语言等。Flink也在逐步完善机器学习算法库,期待Flink向更成熟的机器学习、深度学习方向发展。

\