Apache Flink框架浅析

简介: 集团关于Blink的相关使用文档已经十分齐全,这里不准备再过多赘述。这篇文章准备对Blink所基于的Apache社区开源产品--Flink的架构做一些浅显分析。   一:Flink历史、基本架构及分布式部署   历史 Flink项目最早开始于2010年由柏林技术大学、柏林洪堡大学、哈索普拉特纳研究所共同合作研发的"Stratosphere: Infor
集团关于Blink的相关使用文档已经十分齐全,这里不准备再过多赘述。这篇文章准备对Blink所基于的Apache社区开源产品--Flink的架构做一些浅显分析。
 

一:Flink历史、基本架构及分布式部署

 

历史

Flink项目最早开始于2010年由柏林技术大学、柏林洪堡大学、哈索普拉特纳研究所共同合作研发的"Stratosphere: Information Management on the Cloud"(平流层:云上的信息管理) 项目,Flink最开始是作为该项目一个分布式执行引擎的Fork,到2014年成为Apache基金会下的一个项目,2014年底成为Apache顶级项目。每年一次的Flink Forward是关于Apache Flink最盛大的年度会议。
 

基本架构

Flink是原生的流处理系统,提供high level的API。Flink也提供 API来像Spark一样进行批处理,但两者处理的基础是完全不同的。Flink把批处理当作流处理中的一种特殊情况。在Flink中,所有的数据都看作流,是一种很好的抽象,因为这更接近于现实世界。
 
 
                                                                                    
                 Flink的基本架构图
 
Flink 的主要架构与Spark接近,都基于Master-Slave 的主从模式,从执行顺序上讲:
1:集群启动,启动JobManager 和多个TaskManager;
2:Flink Program程序提交代码,经由优化器/任务图生成器,生成实际需执行的Job,传递至Client;
3:Client将submit提交任务(本质上是发送包含了任务信息的数据流)至JobManager;
4:JobManager分发任务到各个真正执行计算任务的Worker----TaskManager;
5:TaskManager开始执行计算任务,并且定时汇报心跳信息和统计信息给JobManager,TaskManager之间则以流的形式进行数据传输;
 
在以上步骤中,步骤2与Flink集群之间可以不存在归属关系,即我们可以在任何机器上提交作业,只要它与JobManager相通。Job提交之后,Client甚至可以直接结束进程,都不会影响任务在分布式集群的执行。
 

Client:

当用户提交一个Flink程序时,会首先创建一个Client,该Client首先会对用户提交的Flink程序进行预处理,并提交到Flink集群中处理,所以Client需要从用户提交的Flink程序配置中获取JobManager的地址,并建立到JobManager的连接,将Flink Job提交给JobManager。Client会将用户提交的Flink程序组装一个JobGraph, 并且是以JobGraph的形式提交的。一个JobGraph是一个Flink Dataflow,它由多个JobVertex组成的DAG。所以,一个JobGraph包含了一个Flink程序的如下信息:JobID、Job名称、配置信息、一组JobVertex(实际的任务operators)等。
 
JobManager:
JobManager是Flink系统的协调者,它负责接收Flink Job,调度组成Job的多个Task的执行。同时,JobManager还负责收集Job的状态信息,并管理Flink集群中从节点TaskManager。主要包括:
 
RegisterTaskManager——在Flink集群启动的时候,TaskManager会向JobManager注册,如果注册成功,则JobManager会向TaskManager回复消息AcknowledgeRegistration;
SubmitJob——Flink程序内部通过Client向JobManager提交Flink Job,其中在消息SubmitJob中以JobGraph形式描述了Job的基本信息;
CancelJob——请求取消一个Flink Job的执行,CancelJob消息中包含了Job的ID,如果成功则返回消息CancellationSuccess,失败则返回消息CancellationFailure;
UpdateTaskExecutionState——TaskManager会向JobManager请求更新ExecutionGraph中的ExecutionVertex的状态信息,即向JobManager汇报operator具体的执行状态,更新成功则返回true;
 
其他还包括RequestNextInputSplit、JobStatusChanged;
 
 

TaskManager:

TaskManager也是一个Actor(掌管者),它是实际负责执行计算的Worker,在其上执行Flink Job的一组Task。它在启动的时候就设置好了槽位数(Slot),每个 slot 能启动一个 Task,Task 为线程。TaskManager从 JobManager 处接收需要部署的 Task,部署启动后,与自己的上游(任务上存在依赖关系的上游处理节点)建立 Netty 连接,接收数据并处理。每个TaskManager负责管理其所在节点上的资源信息,如内存、磁盘、网络,在启动的时候将资源的状态向JobManager汇报。
 
TaskManager端可以分成两个阶段:
 
注册阶段——TaskManager会向JobManager注册,发送RegisterTaskManager消息,等待JobManager返回AcknowledgeRegistration,然后TaskManager就可以进行初始化过程;
可操作阶段——该阶段TaskManager可以接收并处理与Task有关的消息,如SubmitTask、CancelTask、FailTask。如果TaskManager无法连接到JobManager,这是TaskManager就失去了与JobManager的联系,会自动进入“注册阶段”,只有完成注册才能继续处理Task相关的消息。
 
 
 

基于Yarn层面的结构

 
                                                                                                   
1: Clinet 客户端上传包含Flink和HDFS配置的jars至HDFS,因为YARN客户端需要访问Hadoop的配置以连接YARN资源管理器和HDFS;2: Clinet客户端请求一个YARN容器作为资源管理器-Resource Manager,作用是启动ApplicationMaster;
3: RM分配第一个container去运行AM--AppplicationMaster;
4: AM启动,开始负责资源的监督和管理;
5: Job Manager和AM运行在同一个容器里,都成功启动后,AM知道job管理器(它拥有的主机)的地址;
6:   Job Manager为Task Manager生成一个新的Flink配置, 这样task可连接Job Manager;
7:    AM容器可以作为Flink的web接口服务,YARN代码的所有端口是分配的临时端口, 这可让用户并行执行多个yarn会话;
8: AM启动分配到的容器,这些容器作为Flink的Task Manager,将会从HDFS下载jar和更新配置,集群Run,可接收Job;
 
 

Flink集群的HA方案:

          在Flink的基本架构图中,我们发现这一Master-Slave模式存在单点问题,即:JobManager这个点万一down掉,整个集群也就全完了。Flink一共提供了三种部署模式:Local、Standalone、YARN,除第一种为本地单机模式外,后两者都为集群模式。对于Standalone和YARN,Flink提供了HA机制避免上述单点失败问题,使得集群能够从失败中恢复。
 
YARN模式:
          上段中介绍到Yarn层面的机构,注意到Flink的JobManager与YARN的Application Master(简称AM)是在同一个进程下的。YARN的ResourceManager对AM有监控,当AM异常时,YARN会将AM重新启动,启动后,所有JobManager的元数据从HDFS恢复。但恢复期间,旧的业务不能运行,新的业务不能提交。ZooKeeper(Apache ZooKeeper™ )上还是存有JobManager的元数据,比如运行Job的信息,会提供给新的JobManager使用。对于TaskManager的失败,由JobManager上Akka的DeathWatch机制监听处理。当TaskManager失败后,重新向YARN申请容器,创建TaskManager。
 
Standalone模式:
          对于Standalone模式的集群,可以启动多个JobManager,然后通过ZooKeeper选举出leader作为实际使用的JobManager。该模式下可以配置一个主JobManager(Leader JobManager)和多个备JobManager(Standby JobManager),这能够保证当主JobManager失败后,备的某个JobManager可以承担主的职责。下图为主备JobManager的恢复过程。
 
                                                                                                                                       
 
 
 
 

二:Flink的流式计算架构

分层栈

 
 
                                                                                                                           
 
 
Deployment层:     
            本地、集群,以及商用的云模式,不再赘述;
runtime层:   
           Runtime层提供了支持Flink计算的全部核心实现,比如:支持分布式Stream处理、JobGraph到ExecutionGraph的映射、调度等等,为上层API层提供基础服务;
API层:
            API层主要实现了面向无界Stream的流处理和面向Batch的批处理API,其中面向流处理对应DataStream API,面向批处理对应DataSet API. 简单来说,DataSet和DataStream都是包含了重复项数据的immutable集合,不同的是,在DataSet里,数据是有限的,而对于DataStream,元素的数量可以是无限的。对程序而言,最初的数据集合来源是Flink program 中的源数据,如双11支付数据大屏的线上实时数据来源;然后通过filter、map、flatmap等API,可以对它们进行转换,从而由初始数据集合派生出新集合。注意,集合是immutable的,只可派生出新的,不能修改原有的;
Libraries层:
          Flink应用框架层,根据API层的划分,在API层之上构建的满足特定应用的实现计算框架,也分别对应于面向流处理和面向批处理两类。面向流处理支持:CEP(复杂事件处理)、基于SQL-like的操作(基于Table的关系操作);面向批处理支持:FlinkML(机器学习库)、Gelly(图处理)。
 
 

三:特性分析

高吞吐&低延迟

         简单来说,Flink在流式计算上相比于Spark Streaming & Storm,突出的优势主要是高吞吐&低延迟,如下图所示:
 
                                                                                             
 

支持 Event Time 和乱序事件

                                                                                               
 
Flink 支持了流处理和 Event Time 语义的窗口机制。 在讨论解决消息乱序问题之前,需先定义时间和顺序。在流处理中,时间的概念有两个:
  • Event time :Event time是事件发生的时间,经常以时间戳表示,并和数据一起发送。带时间戳的数据流有,Web服务日志、监控agent的日志、移动端日志等;
  • Processing time :Processing time是处理事件数据的服务器时间,一般是运行流处理应用的服务器时钟。
 
许多流处理场景中,事件发生的时间和事件到达待处理的消息队列时间有各种延迟:
  1. 各种网络延迟;
  2. 数据流消费者导致的队列阻塞和反压影响;
  3. 数据流毛刺,即,数据波动;
  4. 事件生产者(移动设备、传感器等)离线;
 
           上述诸多原因会导致队列中的消息频繁乱序。事件发生的时间和事件到达待处理的消息队列时间的不同随着时间在不断变化,这常被称为时间偏移(event time skew),表示成:“processing time – event time”
 
                                                                                                       
 
        对大部分应用来讲,基于事件的创建时间分析数据比基于事件的处理时间分析数据要更有意义。Flink允许用户定义基于事件时间(event time)的窗口,而不是处理时间。
 
         Flink使用事件时间 clock来跟踪事件时间,其是以watermarks来实现的。watermarks是Flink 源流基于事件时间点生成的特殊事件。 T 时间点的watermarks意味着,小于 T 的时间戳的事件不会再到达。Flink的所有操作都基于watermarks来跟踪事件时间。
 
 

状态计算的exactly-once和容错机制

流程序可以在计算过程中维护自定义状态。
 
                                                                                                                   
       Apache Flink 提供了可以恢复数据流应用到一致状态的容错机制。确保在发生故障时,程序的每条记录只会作用于状态一次(exactly-once),不过也可以降级为至少一次(at-least-once)。这一容错机制通过持续创建分布式数据流的快照来实现。对于状态占用空间小的流应用,这些快照非常轻量,可以高频率创建而对性能影响很小。流计算应用的状态保存在一个可配置的环境,如:master 节点或者 HDFS上。
 
  在遇到程序故障时(如机器、网络、软件等故障),Flink 停止分布式数据流。系统重启所有 operator ,重置其到最近成功的 checkpoint。输入重置到相应的状态快照位置。保证被重启的并行数据流中处理的任何一个 record 都不是 checkpoint 状态之前的一部分。
 
     为了能保证容错机制生效,数据源(例如消息队列或者broker)需要能重放数据流。Apache Kafka 有这个特性,Flink 中 Kafka 的 connector 利用了这个功能。集团的TT系统也有同样功能。
 
                                                                                                             
     
       Flink 分布式快照的核心概念之一就是数据栅栏(barrier)。如上图所示,这些 barrier 被插入到数据流中,作为数据流的一部分和数据一起向下流动。Barrier 不会干扰正常数据,数据流严格有序。一个 barrier 把数据流分割成两部分:一部分进入到当前快照,另一部分进入下一个快照。每一个 barrier 都带有快照 ID,并且 barrier 之前的数据都进入了此快照。Barrier 不会干扰数据流处理,所以非常轻量。多个不同快照的多个 barrier 会在流中同时出现,即多个快照可能同时创建。
 
     Barrier 在数据源端插入,当 snapshot N 的 barrier 插入后,系统会记录当前 snapshot 位置值N (用Sn表示)。例如,在 Apache Kafka 中,这个变量表示某个分区中最后一条数据的偏移量。这个位置值 Sn 会被发送到一个称为 Checkpoint Coordinator 的模块(即 Flink 的 JobManager).
 
  然后 barrier 继续往下流动,当一个 operator 从其输入流接收到所有标识 snapshot N 的 barrier 时,它会向其所有输出流插入一个标识 snapshot N 的 barrier。当 sink operator(DAG 流的终点)从其输入流接收到所有 barrier N 时,它向Checkpoint Coordinator 确认 snapshot N 已完成。当所有 sink 都确认了这个快照,快照就被标识为完成。
 
 

高度灵活的流式窗口Window

             Flink支持在时间窗口,统计窗口,session 窗口,以及数据驱动的窗口,窗口(Window)可以通过灵活的触发条件来定制,以支持复杂的流计算模式。
 
                                                                                   
      来自云邪的描述 ——:“在流处理应用中,数据是连续不断的,因此我们不可能等到所有数据都到了才开始处理。当然我们可以每来一个消息就处理一次,但是有时我们需要做一些聚合类的处理,例如:在过去的1分钟内有多少用户点击了我们的网页。在这种情况下,我们必须定义一个窗口,用来收集最近一分钟内的数据,并对这个窗口内的数据进行计算。”
              窗口可以是时间驱动的(Time Window,例如:每30秒钟),也可以是数据驱动的(Count Window,例如:每一百个元素)。一种经典的窗口分类可以分成:翻滚窗口(Tumbling Window),滚动窗口(Sliding Window),和会话窗口(Session Window)。
 
 

带反压(BackPressure)的连续流模型

         数据流应用执行的是不间断的(常驻)operators。
         Flink streaming 在运行时有着天然的流控:慢的数据 sink 节点会反压(backpressure)快的数据源(sources)。
                                                                                             
          反压通常产生于这样的场景:短时负载高峰导致系统接收数据的速率远高于它处理数据的速率。许多日常问题都会导致反压,例如,垃圾回收停顿可能会导致流入的数据快速堆积,或者遇到大促或秒杀活动导致流量陡增。反压如果不能得到正确的处理,可能会导致资源耗尽甚至系统崩溃。
 
Flink的反压:
         如果你看到一个task的back pressure告警(比如,high),这意味着生产数据比下游操作算子消费的速度快。Record的在你工作流的传输方向是向下游,比如从source到sink,而back pressure正好是沿着反方向,往上游传播。
         举个简单的例子,一个工作流,只有source到sink两个步骤。假如你看到source端有个告警,这意味着sink消费数据速率慢于生产者的生产数据速率。Sink正在向上游进行back pressure。
          绝妙的是,在Spark Streaming和Storm是棘手问题的BackPressure,在Flink中并不成问题。简单来说,Flink无需进行反压,因为系统接收数据的速率和处理数据的速率是自然匹配的。系统接收数据的前提是接收数据的Task必须有空闲可用的Buffer,该数据被继续处理的前提是下游Task也有空闲可用的Buffer。因此,不存在系统接受了过多的数据,导致超过了系统处理的能力。这有点像Java线程中的通用阻塞队列:  一个较慢的接受者会降低发送者的发送速率,因为一旦队列满了(有界队列)发送者会被阻塞。
Flink对反压的具体实现,参考此文:How Apache Flink™ handles backpressure
 

 

相关实践学习
基于Hologres+Flink搭建GitHub实时数据大屏
通过使用Flink、Hologres构建实时数仓,并通过Hologres对接BI分析工具(以DataV为例),实现海量数据实时分析.
实时计算 Flink 实战课程
如何使用实时计算 Flink 搞定数据处理难题?实时计算 Flink 极客训练营产品、技术专家齐上阵,从开源 Flink功能介绍到实时计算 Flink 优势详解,现场实操,5天即可上手! 欢迎开通实时计算 Flink 版: https://cn.aliyun.com/product/bigdata/sc Flink Forward Asia 介绍: Flink Forward 是由 Apache 官方授权,Apache Flink Community China 支持的会议,通过参会不仅可以了解到 Flink 社区的最新动态和发展计划,还可以了解到国内外一线大厂围绕 Flink 生态的生产实践经验,是 Flink 开发者和使用者不可错过的盛会。 去年经过品牌升级后的 Flink Forward Asia 吸引了超过2000人线下参与,一举成为国内最大的 Apache 顶级项目会议。结合2020年的特殊情况,Flink Forward Asia 2020 将在12月26日以线上峰会的形式与大家见面。
目录
相关文章
|
10月前
|
人工智能 数据处理 API
阿里云、Ververica、Confluent 与 LinkedIn 携手推进流式创新,共筑基于 Apache Flink Agents 的智能体 AI 未来
Apache Flink Agents 是由阿里云、Ververica、Confluent 与 LinkedIn 联合推出的开源子项目,旨在基于 Flink 构建可扩展、事件驱动的生产级 AI 智能体框架,实现数据与智能的实时融合。
1561 6
阿里云、Ververica、Confluent 与 LinkedIn 携手推进流式创新,共筑基于 Apache Flink Agents 的智能体 AI 未来
|
存储 Cloud Native 数据处理
从嵌入式状态管理到云原生架构:Apache Flink 的演进与下一代增量计算范式
本文整理自阿里云资深技术专家、Apache Flink PMC 成员梅源在 Flink Forward Asia 新加坡 2025上的分享,深入解析 Flink 状态管理系统的发展历程,从核心设计到 Flink 2.0 存算分离架构,并展望未来基于流批一体的通用增量计算方向。
733 0
从嵌入式状态管理到云原生架构:Apache Flink 的演进与下一代增量计算范式
|
11月前
|
人工智能 运维 Java
Flink Agents:基于Apache Flink的事件驱动AI智能体框架
本文基于Apache Flink PMC成员宋辛童在Community Over Code Asia 2025的演讲,深入解析Flink Agents项目的技术背景、架构设计与应用场景。该项目聚焦事件驱动型AI智能体,结合Flink的实时处理能力,推动AI在工业场景中的工程化落地,涵盖智能运维、直播分析等典型应用,展现其在AI发展第四层次——智能体AI中的重要意义。
3497 27
Flink Agents:基于Apache Flink的事件驱动AI智能体框架
|
12月前
|
消息中间件 存储 Kafka
Apache Flink错误处理实战手册:2年生产环境调试经验总结
本文由 Ververica 客户成功经理 Naci Simsek 撰写,基于其在多个行业 Flink 项目中的实战经验,总结了 Apache Flink 生产环境中常见的三大典型问题及其解决方案。内容涵盖 Kafka 连接器迁移导致的状态管理问题、任务槽负载不均问题以及 Kryo 序列化引发的性能陷阱,旨在帮助企业开发者避免常见误区,提升实时流处理系统的稳定性与性能。
902 0
Apache Flink错误处理实战手册:2年生产环境调试经验总结
|
SQL 大数据 Apache
Apache Flink 2021 最新入门课程 | 图谱精选课程
轻松收获 Flink 生产环境开发技能
Apache Flink 2021 最新入门课程 | 图谱精选课程
|
SQL 人工智能 数据挖掘
Apache Flink:从实时数据分析到实时AI
Apache Flink 是实时数据处理领域的核心技术,历经十年发展,已从学术项目成长为实时计算的事实标准。它在现代数据架构中发挥着关键作用,支持实时数据分析、湖仓集成及实时 AI 应用。随着 Flink 2.0 的发布,其在流式湖仓、AI 驱动决策等方面展现出强大潜力,正推动企业迈向智能化、实时化的新阶段。
1303 9
Apache Flink:从实时数据分析到实时AI
|
SQL 人工智能 API
Apache Flink 2.1.0: 面向实时 Data + AI 全面升级,开启智能流处理新纪元
Apache Flink 2.1.0 正式发布,标志着实时数据处理引擎向统一 Data + AI 平台迈进。新版本强化了实时 AI 能力,支持通过 Flink SQL 和 Table API 创建及调用 AI 模型,新增 Model DDL、ML_PREDICT 表值函数等功能,实现端到端的实时 AI 工作流。同时增强了 Flink SQL 的流处理能力,引入 Process Table Functions(PTFs)、Variant 数据类型,优化流式 Join 及状态管理,显著提升作业稳定性与资源利用率。
1013 0
|
存储 人工智能 大数据
The Past, Present and Future of Apache Flink
本文整理自阿里云开源大数据负责人王峰(莫问)在 Flink Forward Asia 2024 上海站主论坛开场的分享,今年正值 Flink 开源项目诞生的第 10 周年,借此时机,王峰回顾了 Flink 在过去 10 年的发展历程以及 Flink社区当前最新的技术成果,最后展望下一个十年 Flink 路向何方。
1365 33
The Past, Present and Future of Apache Flink
|
SQL Java API
Apache Flink 2.0-preview released
Apache Flink 社区正积极筹备 Flink 2.0 的发布,这是自 Flink 1.0 发布以来的首个重大更新。Flink 2.0 将引入多项激动人心的功能和改进,包括存算分离状态管理、物化表、批作业自适应执行等,同时也包含了一些不兼容的变更。目前提供的预览版旨在让用户提前尝试新功能并收集反馈,但不建议在生产环境中使用。
1946 13
Apache Flink 2.0-preview released
|
SQL 消息中间件 关系型数据库
Apache Doris Flink Connector 24.0.0 版本正式发布
该版本新增了对 Flink 1.20 的支持,并支持通过 Arrow Flight SQL 高速读取 Doris 中数据。
755 21

推荐镜像

更多