flink基本原理

开源流式处理系统在不断地发展,从一开始只关注低延迟指标到现在兼顾延迟、吞吐与结果准确性,在发展过程中解决了很多问题,编程API的易用性也在不断地提高。本文介绍一下 Flink 中的核心概念,这些概念是学习与使用 Flink 十分重要的基础知识,在后续开发 Flink 程序过程中将会帮助开发人员更好地理解 Flink 内部的行为和机制。

这里引用一张图来对常用的实时计算框架做个对比:

flink基本原理

Flink 是有状态的和容错的,可以在维护一次应用程序状态的同时无缝地从故障中恢复。它支持大规模计算能力,能够在数千个节点上并发运行。它具有很好的吞吐量和延迟特性。同时,Flink 提供了多种灵活的窗口函数。Flink 在流式计算里属于真正意义上的单条处理,每一条数据都触发计算,而不是像 Spark 一样的 Mini Batch 作为流式处理的妥协。Flink的容错机制较为轻量,对吞吐量影响较小,而且拥有图和调度上的一些优化,使得 Flink 可以达到很高的吞吐量。而 Strom 的容错机制需要对每条数据进行ack,因此其吞吐量瓶颈也是备受诟病。

二、工作原理

Flink基本工作原理如下图:

flink基本原理

JobClient:负责接收程序,解析和优化程序的执行计划,然后提交执行计划到JobManager。这里执行的程序优化是将相邻的Operator融合,形成Operator Chain,Operator的融合可以减少task的数量,提高TaskManager的资源利用率。

JobManagers:负责申请资源,协调以及控制整个job的执行过程,具体包括,调度任务、处理checkpoint、容错等等。

TaskManager:TaskManager运行在不同节点上的JVM进程,负责接收并执行JobManager发送的task,并且与JobManager通信,反馈任务状态信息,如果说JobManager是master的话,那么TaskManager就是worker用于执行任务。每个TaskManager像是一个容器,包含一个或者多个Slot。

Slot:Slot是TaskManager资源粒度的划分,每个Slot都有自己独立的内存。所有Slot平均分配TaskManager的内存,值得注意的是,Slot仅划分内存,不涉及CPU的划分,即CPU是共享使用。每个Slot可以运行多个task。Slot的个数就代表了一个程序的最高并行度。

Task:Task是在operators的subtask进行链化之后形成的,具体Flink job中有多少task和operator的并行度和链化的策略有关。

SubTask:因为Flink是分布式部署的,程序中的每个算子,在实际执行中被分隔为一个或者多个subtask,运算符子任务(subtask)的数量是该特定运算符的并行度。数据流在算子之间流动,就对应到SubTask之间的数据传输。Flink允许同一个job中来自不同task的subtask可以共享同一个slot。每个slot可以执行一个并行的pipeline。可以将pipeline看作是多个subtask的组成的。

三、核心概念

1、Time(时间语义)

Flink 中的 Time 分为三种:事件时间、达到时间与处理时间。

1)事件时间:是事件真实发生的时间。

2)达到时间:是系统接收到事件的时间,即服务端接收到事件的时间。

3)处理时间:是系统开始处理到达事件的时间。

在某些场景下,处理时间等于达到时间。因为处理时间没有乱序的问题,所以服务端做基于处理时间的计算是比较简单的,无迟到与乱序数据。

Flink 中只需要通过 env 环境变量即可设置Time:

//创建环境上下文 val env = StreamExecutionEnvironment.getExecutionEnvironment // 设置在当前程序中使用 ProcessingTime env.setStreamTimeCharacteristic(TimeCharacteristic.ProcessingTime);

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpszyj.html