Flink: 基本概念与架构

2020/04/21 Flink 共 2931 字,约 9 分钟

Flink是一个分布式处理流式或者批量数据的系统,适用于多种数据处理应用,如实时分析,历史数据处理,迭代算法等,将它们转化为拥有流水机制和容错机制的数据流进行处理。

优势

Apache Flink 同时支持流式及批量分析应用,即批流一体,所以Flink在实时数仓和实时ETL中有天然的优势:

  • 状态管理,实时数仓里面会进行很多的聚合计算,这些都需要对于状态进行访问和管理,Flink 支持强大的状态管理
  • 表义能力,Flink 提供极为丰富的多层次 API,包括Stream API、Table API及Flink SQL
  • 生态完善,实时数仓的用途广泛,Flink 支持多种存储(HDFS、ES 等);
  • 批流一体,Flink 已经在将流计算和批计算的 API 进行统一

相对于Spark Streaming,有以下优势

  • 架构
    • Spark Streaming的架构是基于Spark的,本质是微批处理,可以把Spark Streaming理解为时间维度上的 Spark DAG
    • Flink 程序启动后,会根据用户的代码处理成逻辑执行计划StreamGraph,然后优化成优化的逻辑执行计划 JobGraph,JobManager会根据 JobGraph生成物理执行计划ExecutionGraph。当很多个ExecutionGraph分布在集群中,就会形成一张网状的拓扑结构
  • 容错
    • 对于Spark Streaming 任务,我们可以配置对应的 checkpoint。当任务出现 failover 的时候,会从 checkpoint 重新加载,使得数据不丢失。但是这个过程会导致原来的数据重复处理,不能做到精确一次处理语义
    • Flink基于两阶段提交实现了精确一次处理语义

事件驱动

事件驱动型应用是一类具有状态的应用,它从一个或多个事件流提取数据,并根据到来的事件触发计算、状态更新或其他外部动作。在传统架构中,我们需要读写远程事务型数据库,比如MySQL。在事件驱动应用中数据和计算不会分离,状态保存在本地,所以具有更高的吞吐和更低的延迟。

Flink 的以下特性完美的支持了事件驱动型应用:

  • 高效的状态管理,Flink 自带的 State Backend可以很好的存储中间状态信息
  • 丰富的窗口支持,Flink 支持包含滚动窗口、滑动窗口及其他窗口
  • 多种时间语义,Flink 支持 Event Time、Processing Time 和 Ingestion Time
  • 不同级别的容错,Flink 支持 At Least Once 或 Exactly Once 容错级别

架构

部署模式

  • 本地模式
    • Local
      • 模拟cluster集群,仅启动JobManager完成应用的运行
  • 集群模式
    • Standalone
      • 部署相对简单,可以支持小规模,少量的任务运行
      • 缺少系统层面对集群中Job的管理,容易遭成资源分配不均匀
      • 资源隔离相对简单,任务之间资源竞争严重
    • Yarn
      • Yarn-cluster
        • 一个Flink任务提交对应一个Yarn的application,任务之间不会有影响
      • Yarn-session
        • 创建session以后,Yarn会启动一个ApplicationMaster和指定数目的Container。本质上ApplicationMaster扮演的是JobManager的角色,Contaienr扮演的是TaskManager的角色,类似于启动一个Flink的集群
        • 之后提交所有的Flink任务在指定的Yarn application运行,Yarn application的失败将会导致所有运行在其上的Flink任务的失败
  • 云模式
    • 部署在云服务器上

Runtime层

Runtime层以JobGraph的形式接收程序并执行

  • Client: Client 根据用户传入的参数选择使用Yarn-cluster模式、Standalone模式还是Yarn-session模式将 Flink程序转化为数据流图,提交给JobManager去执行
  • JobManager
    • 集群管理者,协调JobGraph的分布式执行
    • 负责调度任务、协调 checkpoints、协调故障恢复、收集 Job 的状态信息,并管理 Flink 集群中的从节点 TaskManager
  • TaskManager
    • 实际负责执行计算的 Worker,在其上执行Flink Job的一组Task。维护缓冲池以缓冲或物化流,并维护网络连接以在算子之间交换数据流
    • 所在节点的管理员,负责把该节点上的服务器信息比如内存、磁盘、任务运行情况等向JobManager汇报

API&LIB层

DataSet用于处理有限数据集即批处理,而DataStream用于处理无界数据流即流处理DataStream APIDataSet API均通过单独的编译过程生成JobGraphs,即由有状态算子连接的数据流DAG,交由下层Runtime层去执行。

Flink自带了一些用于特定领域的库,这些库会生成DataSet APIDataStream API程序。目前,FlinkML用于机器学习,Gelly用于图计算,而Table用于SQL操作。

资源和资源组

在 Flink 集群中,一个TaskManger就是一个 JVM 进程,并且会用独立的线程来执行Task。如下图所示,每个TaskManger中含有固定的slot,体现了其并发执行能力,slot为运行Task的容器,起到了内存隔离的作用,对 CPU 不起作用。那么运行在同一个 JVM 的 task 可以共享TCP连接,减少网络传输,在一定程度上提高了程序的运行效率,降低了资源消耗

slot共享

Flink 还允许将不能形成算子链的两个操作放在一个slot中执行。一些简单的map和filter算子所需要的资源不多,但是有些算子比如window、group by则需要更多的计算资源才能满足计算所需。资源需求大的算子可以共用其他的slot,提高整个集群的资源利用率。比如下图中的flatmap和key&sink放在一个slot里执行以达到资源共享的目的。

算子链

这么做是因为 Flink 本身提供了非常有效的任务优化手段,因为 task 是在同一个线程中执行,那么可以有效减少线程间上下文的切换,并且减少序列化/反序列化带来的资源消耗,从而在整体上提高任务的吞吐量,是对执行效率的优化

符合以下条件的算子将合并为算子链

  • 上下游算子的并行度相同
  • 下游算子的输入StreamEdge只能有一个

  • 上下游算子实例处于同一个 Slotsharing Group中(之后再提)
  • 下游节点的连接策略为ALWAYS(可以与上下游链接,mapflatmapfilter等默认是ALWAYS)
  • 上游节点的连接策略为ALWAYS或HEAD(只能与下游链接,不能与上游链接,Source默认是HEAD)
  • 上下游算子之间没有数据shuffle
  • 没有禁用算子链

REFERENCE

  1. CARBONE P, KATSIFODIMOS A, EWEN S, 等. Apache flink: Stream and batch processing in a single engine[J]. Bulletin of the IEEE Computer Society Technical Committee on Data Engineering, IEEE Computer Society, 2015, 36(4).
  2. flink官方文档

文档信息

Search

    Table of Contents