Apache Flink 论文学习

Posted by Ink Bai on 2019-03-03     & views

本文是 Flink 论文 的学习笔记。

基本介绍

一般来说,实时计算的结果要求延迟低,但是可能会有一定的误差,而批处理的结果一般会有一定的延迟,但是结果准确。对应到传统的计算框架,就会出现两套逻辑和两套代码来分别实现实时和批处理的计算。

Flink 将流式计算和批处理统一了起来,首先,所有的数据其实都可以按照流式进行处理,只要我们与一些可持久化且可重新消费的消息队列系统一起使用,如 Apache Kafka 和 Amazon Kinesis,不同类型的数据都可以看作是流数据,不管是实时处理单条记录,或是在一个大窗口下持续性的聚合数据,还是处理 TB 级别的历史数据,流处理程序都不会作出明显的区分。

上面这种形式是通过消息中间件强行把批数据流化,但是现实情况是有的时候不能这么搞,的确需要对一个整体的数据集进行处理。例如对整个数据集做一些复杂的查询就很方便,并且对于某些分析类的应用(一般分析类的应用都是批处理),可能还没有能够很高效的在流数据上执行的算法。

这篇论文阐述了以下内容:

  • 提出了同时包含批处理和流处理的统一框架,同时对批数据做了特殊的优化。
  • 展示了如何将流、批、迭代和交互式分析表示成容错的数据流。
  • 讨论了如何通过灵活的窗口机制建立一个完备的流分析系统,同时在其之上建立批处理系统。

看到这里我有几个问题:

  1. 如何将批流统一处理的呢?底层都是转化为数据流的形式了吗?
  2. 针对批处理的优化是怎样的?为什么要优化?是为了使其变成流吗?
  3. 窗口机制是个什么东西?
  4. Flink 核心是流处理,那么流处理的过程是怎样的?
  5. 同样的,批处理的完整过程是怎样的?

让我们带着问题接着往下走。

系统架构

如图所示,Flink 的软件栈主要有四层,分别是部署层、核心层、API 层和类库。

Flink 的核心就是分布式的数据流引擎,在上面执行数据流程序,这个运行时的程序的整个过程是一个在数据流上进行有状态操作的 DAG。

运行时的程序会执行有状态的操作。

下图展示了 Flink 集群模式运行时的情况:

可以看到一个 Flink 集群主要由三部分组成:client、Job Manager 和 Task Manager(至少一个)。程序代码放在 client 里,然后 clinet 会把程序转换成数据流图,并且提交给 Job Manager。这个转换过程还会检验各个操作之间数据转换的数据类型、建立序列化器等,对于批处理程序还会有额外的基于成本的查询优化过程。

Job Manager 会协调数据流的分布式执行。它会追踪每一个操作和流的状态和进度,调度新的操作并且协调检查点和相应的恢复机制。当配置了高可用以后,Job Manager 可以把每个检查点处一个最下的元数据集持久化到一个具有容错性的存储中,这样备用的检查点就可以重建检查点并且恢复数据流的执行。

Task Manager 是真正进行数据处理的地方,一个 TaskManager 执行一个或多个操作,并且向 JobManager 报告它们的状态。TaskManager 会维持一个缓存池来缓存或者实体化流,并且建立网络连接以交换多个操作之间的数据。

妈蛋,看完这部分内容又产生了新的问题:

  1. 操作是一个什么概念,类似于 Spark 中的算子吗?
  2. 基于成本的查询优化的原理?(感觉开了一个大坑)

共同的结构:流式数据流

我们可以通过多种不同的 API 来写 Flink 程序,但是这些程序最终都会被编译成一个通用的表示:数据流图。数据流图在 Flink 的运行时引擎上执行。

数据流图