关于Flink:袋鼠云基于Flink构建实时计算平台的总体架构和关键技术点

46次阅读

共计 5383 个字符,预计需要花费 14 分钟才能阅读完成。

平台建设的背景

传统离线数据开发时效性较差,无奈满足疾速迭代的互联网需要。随同着以 Flink 为代表的实时技术的飞速发展,实时计算被越来越多的企业应用,然而在应用中,各种问题也随之而来。比方开发者应用门槛高、产出的业务数据品质没有保障、企业短少对立平台治理难以保护等。在诸多不利因素的影响下,咱们决定利用现有的 Flink 技术构建一套残缺的实时计算平台。

平台总体架构

从总体架构来看,实时计算平台大体能够分为三层:

  • 计算平台
  • 调度平台
  • 资源平台。

每层承当着相应的性能,同时层与层之间又有交互,合乎高内聚、低耦合的设计原子,架构图如下:

计算平台

间接面向开发人员应用,能够依据业务需要接入各种内部数据源,提供后续工作应用。数据源配置实现后,就能够在下面做基于 Flink 框架可视化的数据同步、SQL 化的数据计算的工作,并且能够对运行中的工作进行多维度的监控和告警。

调度平台

该层接管到平台传过来的工作内容和配置后,接下来就是比拟外围的工作,也是下文中重点开展的内容。这里先做一个大体的介绍,依据工作类型的不同将应用不同的插件进行解析。

  • 数据同步工作:接管到下层传过来的 json 后,进入到 FlinkX 框架中,依据数据源端和写出指标端的不同生成对应的 DataStream,最初转换成 JobGraph。
  • 数据计算工作:接管到下层传过来的 SQL 后,进入到 FlinkStreamSQL 框架中,解析 SQL、注册成表、生成 transformation,最初转换成 JobGraph。

调度平台将失去的 JobGraph 提交到对应的资源平台,实现工作的提交。

资源平台

目前能够对接多套不同的资源集群,并且也能够对接不同的资源类型,如:yarn 和 k8s.

数据同步和数据计算

在调度平台中,接管到用户的工作后就开始了前面的一系列的转换操作,最终让工作运行起来。咱们从底层的技术细节来看如何基于 Flink 构建实时计算平台,以及如何应用 FlinkX、FlinkStreamSQL 做一站式开发。

FlinkX

作为数据处理的第一步,也是最根底的一步,咱们来看看 FlinkX 是如何在 Flink 的根底上做二次开发。用户只须要关注同步工作的 json 脚本和一些配置,无需关怀调用 Flink 的细节,且 FlinkX 反对下图中所展现的性能。

咱们先看下 Flink 工作提交中波及到的流程,其中的交互流程图如下:

那么 FlinkX 又是如何在 Flink 的根底对上述组件进行封装和调用,使得 Flink 作为数据同步工具应用更加简略?

次要从 Client、JobManager、TaskManager 三个局部进行扩大,波及到的内容如下图:

Client 端

FlinkX 对原生的 Client 做了局部定制化开发,在 FlinkX-launcher 模块下,次要有以下几个步骤:

  1. 解析参数,如:并行度、savepoint 门路、程序的入口 jar 包 (平时写的 Flink demo)、Flink-conf.yml 中的配置等;
  2. 通过程序的入口 jar 包、内部传入参数、savepoint 参数生成 PackagedProgram;
  3. 通过反射调用 PackagedProgram 中指定的程序的入口 jar 包的 main 办法,在 main 办法中,通过用户配置的 reader 和 writer 的不同,加载对应的插件;
  4. 生成 JobGraph,将其中须要的资源 (Flink 须要的 jar 包、reader 和 writer 的 jar 包、Flink 配置文件等) 退出到 YarnClusterDescriptor 的 shipFiles 中,最初 YarnClusterDescriptor 就能够和 yarn 交互启动 JobManager;
  5. 工作提交胜利后,Client 端就可失去 yarn 返回的 applicationId,后续既能够通过 application 跟踪工作的状态。

JobManager 端

Client 端提交完后,随后 yarn 启动 jobmanager,jobmanager 会启动一些本人的外部服务,并且会构建 ExecutionGraph。

在这个过程中,FlinkX 次要做了以下两件事:

  1. 用不同插件重写 InputFormat 接口中的 createInputSplits 的办法创立分片,在上游数据量较大或者须要多并行度读取的时候,该办法就起到给每个并行度设置不同的分片的作用。比方:在两个并行度读取 MySQL 时,通过配置的分片字段 (比方自增主键 ID)。

    • 第一个并行度读取 SQL 为:select * from table where id mod 2=0;
    • 第二个并行度读取 SQL 为:select * from table where id mod 2=1;
  2. 分片创立完后,通过 getInputSplitAssigner 按程序返回调配给各个并发实例。

TaskManager 端

在 TaskManager 端接管到 JobManager 调度过去的 task 之后,就开始了本人的生命周期的调用,次要蕴含以下几个重要的阶段:

  1. initialize-operator-states(): 循环遍历该 task 所有的 operator,并调用实现了 CheckpointedFunction 接口的 initializeState 办法,在 FlinkX 中为 DtInputFormatSourceFunction 和 DtOutputFormatSinkFunction,该办法在工作第一次启动的时候会被调用,作用是复原状态,当工作失败时能够从最近一次的 checkpoint 复原读取地位,从而达到能够续跑的目标,如下图所示:

  1. open-operators(): 该办法调用 OperatorChain 中所有 StreamOperator 的 open 办法,最初调用的是 BaseRichInputFormat 中的 open 办法。该办法次要做以下几件事:

    • 初始化累加器,记录读入、写出的条数、字节数;
    • 初始化自定义的 Metric;
    • 开启限速器;
    • 初始化状态;
    • 关上读取数据源的连贯 (依据数据源的不同,每个插件各自实现)。
  2. run(): 调用 InputFormat 中的 nextRecord 办法、OutputFormat 中的 writeRecord 办法进行数据的解决。
  3. close-operators(): 做一些敞开操作,例如调用 InputFormat、OutputFormat 的 close 办法等,并做一些清理工作。

以上就是 TaskManager 中 StreamTask 整体的生命流程,除了下面介绍的 FlinkX 如何调用 Flink 接口,FlinkX 还有如下一些个性。

  • 自定义累加器: 累加器是从用户函数和操作中,分布式地统计或者聚合信息。每个并行实例创立并更新本人的 Accumulator 对象, 而后合并收集不同并行实例,在作业完结时由零碎合并,并可将后果推动到普罗米修斯中,如图:

  • 反对离线和实时同步: 咱们晓得 FlinkX 是一个反对离线和实时同步的框架,这里以 MySQL 数据源为例,看看是如何实现的。

    • 离线工作:在 DtInputFormatSourceFunction 的 run 办法中会调用 InputFormat 的 open 办法,读取数据记录到 resultSet 中,之后再调用 reachedEnd 办法,来判断 resultSet 的数据是否读取完。如果读取完,就走后续的 close 流程。
    • 实时工作:open 办法和离线统一,在 reachedEnd 时判断是否是轮询工作,如果是,则会进入到距离轮询的分支中,将上一次轮询读取到的最大的一个增量字段值,作为本次轮询的开始地位,并进行下一次轮询,轮询流程图如下:

  • 脏数据管理和谬误管制: 把写入数据源时出错的数据记录下来,并把谬误起因分类,而后写入配置的脏数据表。谬误起因目前有:类型转换谬误、空指针、主键抵触和其它谬误四类。谬误管制是基于 Flink 的累加器,在运行过程中记录出错的记录数,而后在独自的线程里定时判断谬误的记录数是否曾经超出配置的最大值,如果超出,则抛出异样使工作失败。这样能够对数据精确度要求不同的工作,做不同的谬误管制,管制流程图如下:

  • 限速器: 一些上游数据产生过快的工作,会对上游数据库造成较大的压力,故而须要在源端做一些速率管制,FlinkX 应用的是令牌桶限流的形式管制速率。如下图,当源端产生数据的速率达到某个阈值时,就不会再读取新的数据,在 BaseRichInputFormat 的 open 阶段也初始化了限速器。

以上就是 FlinkX 数据同步的基本原理,然而数据业务场景中数据同步只是第一步,因为 FlinkX 目前的版本中只有 ETL 中的 EL,并不具备对数据的转换和计算的能力,故而须要将产生的数据流入到上游的 FlinkStreamSQL。

FlinkStreamSQL

基于 Flink,对其实时 SQL 进行扩大,次要扩大了流与维表的 join,并反对原生 Flink SQL 所有的语法。目前 FlinkStreamSQL source 端只能对接 Kafka,所以默认上游数据起源都是 Kafka。

接下来咱们看看 FlinkStreamSQL 如何在 Flink 根底上做到,用户只须要关注业务 SQL 代码,如何调用 Flink api 来屏蔽底层。整体流程和下面介绍的 FlinkX 根本相似,不同点在 Client 端,这里次要包含 SQL 解析、注册表、执行 SQL 三个局部。

解析 SQL

这里次要是解析用户写的 create function、create table、create view、insert into 四种 SQL 语句,封装到结构化的 SQLTree 数据结构中。SQLTree 中蕴含了自定义函数汇合、内部数据源表汇合、视图语句汇合、写数据语句汇合。

表注册

失去了下面解析的 SQLTree 之后,就能够将 SQL 中 create table 语句对应的内部数据源汇合作为表注册到 tableEnv 中,并且将用户自定的 UDF 注册进 tableEnv 中。

执行 SQL

将数据源注册成表之后,就能够执行前面 insert into 的 SQL 语句了,执行 SQL 这里会分两种状况:

  • SQL 中没有关联维表,就间接执行 SQL;
  • SQL 中关联了维表,因为在 Flink 晚期版本中不反对维表 join 语法,咱们在这块做了扩大,不过在 FlinkStreamSQL v1.11 之后和社区放弃了统一,反对了和维表 join 的语法。依据维表的类型不同,应用不同的关联形式:

    • 全量维表:将上游数据作为输出,应用 RichFlatMapFunction 作为查问算子,初始化时将数据全表捞到内存中,而后和输出数据组拼失去打宽后的数据,之后从新注册一张大表,供后续 SQL 应用。
    • 异步维表:将上游数据作为输出,应用 RichAsyncFunction 作为查问算子,并将查问失去的数据应用 LRU 缓存,而后和输出数据组拼失去打宽后的数据,之后从新注册一张大表,供后续 SQL 应用。

下面介绍的就是 FlinkX 和 FlinkStramSQL 在 Client 端的不同之处,因为 source 端只有 Kafka 且应用了社区原生的 Kafka-connector,所以在 jobmanager 端也没有数据分片的逻辑,taskmanager 逻辑和 FlinkX 根本相似,这里不再介绍。

工作运维

当应用 FlinkX 和 FlinkStreamSQL 开发完业务之后,接下来进入到了工作运维阶段。在运维阶段,咱们次要在工作运行信息、数据进出指标 metrics、数据提早、反压、数据歪斜等维度做了监控。

工作运行信息

咱们晓得 FlinkStreamSQL 是基于 FlinkSQL 封装的,所以在提交工作运行时最终还是走的 FlinkSQL 的解析、验证、逻辑打算、逻辑打算优化、物理打算,最初将工作运行起来,也就失去了咱们常常看见的 DAG 图:

然而因为 FlinkSQL 对工作做了很多优化,以至于咱们只能看到如上图的大体 DAG 图,子 DAG 图外面的一些细节咱们是没法直观的看到产生了什么事件。所以咱们在原来生成 DAG 图的形式上进行了肯定的革新,这样就能直观的看到子 DAG 图中每个 Operator 和每个并行度外面产生了什么事件,有了具体的 DAG 图后,其余的一些监控维度就能直观的展现,比方:数据输入输出、延时、反压、数据歪斜,在呈现问题时就能具体定位到,如下图的反压:

理解了下面的构造后,咱们来看看它是如何实现的。咱们晓得在 Client 提交工作时,会生成 JobGraph,JobGraph 中的 taskVertices 汇合就封装了上图残缺的信息,咱们将 taskVertices 生成 json 后,再联合 LatencyMarker 和相干的 metrics,即可在前端生成上图,并做相应的告警。

除了下面的 DAG 以外,还有自定义 metrics、数据延时获取等,这里不具体介绍,有趣味的同学能够参考 FlinkStreamSQL 我的项目。

应用案例:

通过下面的介绍后,咱们看下在平台上应用的理论案例。上面展现了一个残缺的案例:应用 FlinkX 将 MySQL 中新增用户数据实时同步到 Kafka,而后应用 FlinkstreamSQL 生产 Kafka 实时计算每分钟新增用户数,产出后果落库到上游 MySQL,供业务应用。

实时同步 MySQL 新增数据

实时计算每分钟新增用户数

运行信息

整体 DAG,能够直观的显示下面提到的多项指标

解析后的具体 DAG 图,能够看到子 DAG 外部的多项指标


以上就是 Flink 在袋鼠云实时计算平台的总体架构和一些要害的技术点,如有不足之处欢送大家指出。

正文完
 0