Flink架构(一)- 系统架构
1. 系统架构
Flink是一个分布式系统,用于有状态的并行数据流处理。也就是说,Flink会分布式地运行在多个机器上。在分布式系统中,常见的挑战有:如何对集群中的资源进行分配与管理、协调进程、数据存储的高可用、以及异常恢复。
Flink自身并未实现这些功能,而仅关注在它自身的核心功能 - 分布式数据流处理。对于分布式集群的管理,由运行在它之下的集群完成,并提供基础设施与服务。Flink与常见集群资源管理器契合度良好,例如Apache Mesos,YARN,以及Kubernetes。当然它也可以配置为stand-alone集群。Flink并不提供可靠的分布式存储。它直接使用其他分布式文件系统如HDFS、S3等。对于在HA设置下的leader选举,它依赖于ZooKeeper。
在这章我们会介绍Flink的各个组件,以及它们如何相互作用,以运行一个application。我也也会讨论Flink 应用的两种部署模式,以及它们如何分发、执行任务。最后,介绍在HA模式下Flink如何工作。
Flink组件
在Flink中有四个不同的组件,它们共同协作运行流程序。这些组件为:一个JobManager,一个ResourceManager,一个TaskManager,以及一个Dispatcher。Flink是由Java和Scala实现,所以这些组件全部运行在JVM中。每个组件的职责为:
·JobManager:主(master)进程,用于管理单个application的执行。每个application都由一个不同的JobManager管理。JobManager会接收application并执行。一个application包含:一个JobGraph,一个逻辑数据流图(logical dataflow graph),以及一个Jar文件(包含了所有需要的类、lib库以及其他资源)。JobManager将JobGraph转化为一个物理数据流图(physical dataflow graph),称为ExecutionGraph。ExecutionGraph由一些可以并行执行的任务(tasks)组成。JobManager向ResourceManager申请必须的计算资源(称为TaskManager slots)用于执行任务。一旦JobManager收到足够的TaskManager slots,它将ExecutionGraph中的task分发到TaskManager,然后执行。在执行过程中,JobManager负责任何需要中心协调(central coordination)的操作,例如检查点(checkpoints)的协调
·ResourceManager:Flink 可以整合多个ResourceManager,例如YARN,Mesos,Kubernetes以及standalone 部署。ResourceManager负责管理TaskManager slots,也就是Flink的一个资源处理单元。当JobManager 申请TaskManager slots时,ResourceManager 会分配空闲slot给它。如果RM并没有足够的slots满足JobManager的请求,则RM can talk to a resource provider to provision containers in which TaskManager processes are started。RM也负责关闭空闲的TaskManagers,以释放计算资源。
·TaskManagers:是Flink的worker 进程。一般来说,会有多个TaskManagers运行在一个配置好的Flink 集群中。每个TaskManager提供了具体数量的 slots。Slots的数量限制了TaskManager可以运行的task数量。在TaskManager启动后,它会向ResourceManager注册它的slots。在接受到RM的指令后,TaskManager会向JobManager提供它的slots。JobManager即可分配任务到这些slots,并开始执行这些任务。在执行过程中,对于同一个application的不同taks,运行在它们之下的TaskManager 之间会互相交换数据。
·Dispatcher 提供了一个REST 接口,用于提交application执行。当一个application被提交,Dispatcher会启动一个JobManager并将application交给它。REST接口使得Dispatcher可以作为一个(位于防火墙之后的)HTTP 入口服务提供给外部。Dispathcher也运行了一个web控制面板,用于提供job执行的信息。取决于一个application如何提交执行,dispathcher可能并不是必须的。
下图展示的是:在提交一个application后,Flink的组件之间如何协作运行此应用:

上图是一个较为High-Level的角度。取决于部署的集群不同(例如YARN,standalone等),一些步骤可以被省略,亦或是有些组件会运行在同一个JVM进程中。
应用部署
Flink application 可以使用以下两种不同的方式部署:
1. 框架方式
·在这个模式下,Flink应用被打包成一个Jar文件,并由客户端提交到一个运行的服务(running service)。这个服务可以是一个Flink Dispatcher,一个FlinkJobManager,或是Yarn ResourceManager。如果application被提交给一个JobManager,则它会立即开始执行这个application。如果application被提交给了一个Dispatcher,或是Yarn RM,则它会启动一个JobManager,然后将application交给它,JobManager开始执行此应用。
2. 库(Library)模式
·在这个模式下,Flink Application 会被打包在一个container 镜像,例如一个Docker 镜像。此镜像包含了运行JobManager和ResourceManager的代码。当一个容器从镜像启动后,它会自动启动ResourceManager和JobManager,并提交打包好的应用。另一种方法是:将应用打包到镜像后,用于部署TaskManager容器。从此镜像启动的容器会自动启动一个TaskManager,它会连接ResourceManager并注册它的slots。一般来说,这些镜像的启动以及失败重启由一个外部的资源管理器管理(如Kubernetes)。
框架模式遵循了传统的提交任务到集群的方式。在库模式下,没有运行的Flink服务。它是将Flink作为一个库,与application一同打包到了一个容器镜像。这个部署模式在微服务架构中较为常见
任务执行
一个TaskManager可以同时执行多个任务。这些task可以是同一个operator(也就是数据并行)的、或是不同的operator(也就是task并行)的,亦或是另一个不同application的(job并行)一组tasks的子集。TaskManager提供了明确个数的processing slots,用于控制可以并行执行的任务数。一个slot可以执行application的一个分片(一个operator的一个并行task)。下图展示了TaskManager,slots,tasks以及operators之间的关系:

最左边是一个JobGraph – application的非并行表示,包含了5个operator。A和C是数据源,E是输出端(sink)。C和E有2个并行,其他的有4个并行。因为最高的并行度是4,所以应用需要至少四个slot执行任务。给定两个TaskManager,每个各有两个slot,这种情况下需求是满足的。JobManager将JobGraph转化为ExecutionGraph,并将任务分配到四个可用的slot上。对于有4个并行任务的operator,它的task会分配到每个slot上。对于有2个并行任务的operator C和E,它们的任务被分配到slot 1.1、2.1 以及 slot 1.2、2.2。将tasks调度到slots上,可以让多个tasks跑在同一个TaskManager内,也就可以是的tasks之间的数据交换更高效。然而将太多任务调度到同一个TaskManager上会导致TaskManager过载,继而影响效率。之后我们会讨论如何控制任务的调度。
TaskManager在同一个JVM中以多线程的方式执行任务。线程较进程会更轻量级,但是线程之间并没有非常严格的将任务互相隔离。所以,单个误操作的任务可能会kill掉整个TaskManager进程,以及运行在此进程上的所有任务。通过为每个TaskManager配置单独的slot,可以将application相互隔离。依赖于TaskManager内部的多线程,以及在一台实例上配置部署多个TaskManager,Flink可以为性能与资源隔离提供更灵活的权衡。
高可用设置
流应用一般设计为7 x 24 小时运行。所以很重要的一点是:即使在出现了进程挂掉的情况,应用仍需要继续保持执行。为了从故障恢复,系统需要重启进程、重启应用并恢复它的状态。接下来我们会介绍Flink如何重启失败的进程。
1. TaskManager 失败
正如前文提到,Flink需要足够数目的slot,以执行一个应用的所有任务。假设一个Flink配置有4个TaskManager,每个TM提供2个slot,则一个流程序最高可以以8个并行单位执行。如果其中一个TaskManager失败,可用的slots会降到6。在这种情况下,JobManager会要求ResourceManager提供更多的slots。如果此要求无法完成 - 例如应用跑在一个standalone集群 – JobManager在有足够的slots之前,无法重启此application。应用的重启逻辑决定了JobManager的重启频率,以及两次尝试之间的时间间隔。
2. JobManager失败
比TaskManager失败更严重的问题是JobManager失败。JM控制整个流应用的执行,并维护执行中的元数据,例如指向已完成的检查点的指针。若是对应的JobManager消失,则流程序无法继续运行。也就是说JobManager在Flink应用中是单点故障。为了克服这个问题,Flink支持高可用模式,在源JM消失后,可以将一个job的状态与元数据迁移到另一个JobManager,并继续执行。
Flink的高可用模式基于ZooKeeper。若是在HA模式下运行,则JobManager将JobGraph以及所有必须的metadata(例如应用的jar文件)写入到一个远程持久性存储系统中。此外,JM会写一个指针信息(指向存储位置)到Zookeeper的数据存储中。在执行一个application的过程中,JM接收每个独立task检查点的state句柄(也就是存储位置)。根据一个检查点的完成情况(当所有任务已经成功地将它们的state写入到远程存储), JobManager写入state句柄到远程存储,以及写入指针(指向远程存储的指针)到ZooKeeper。所以,所有需要(在一个JM失败后)被还原的信息被存储在远程存储,而ZooKeeper持有指向此存储位置的指针。下图描述了此设计:

当一个JM失败,所有属于这个application的任务会自动取消。一个新的JM接管失败JM的工作,并执行以下操作:
1.从ZooKeeper请求存储位置(storage location),从远端存储获取JobGraph,Jar文件,以及application上次checkpoint的状态句柄(state handles)
2.从ResourceManager请求slots,以继续执行application
3.重启application并重制它所有的tasks到上一个完成了的checkpoint
当一个application是以库部署的形式运行(如Kubernetes),失败的JobManager或TaskManager 容器会由容器服务自动重启。当运行在YARN或Mesos之上时,JobManager或TaskManager进程会由Flink自动触发重启。在standalone模式下,Flink并未提供为失败进程重启的工具。所以次模式下可以运行一个standby JM和TM,用于接管失败的进程。
References:
Vasiliki Kalavri, Fabian Hueske. Stream Processing With Apache Flink. 2019
Flink架构(一)- 系统架构的更多相关文章
- 【已转移】【Java架构:系统架构理论】一篇文章搞掂:RESTful
一.定义 1.起源 来源:Roy Fielding的博士论文. 目的:理解和评估以网络为基础的应用软件的架构设计,得到一个功能强.性能好.适宜通信的架构. 定义:一种实现软件通信的架构风格.设计风格, ...
- Android系统架构与系统源码目录
前言 技术博客终于可以恢复正常的更新速度了,原因是我编写的进阶书籍的初稿已经完成,窃以为它将会是Android应用书籍中最有深度的一本,可以说是<Android开发艺术探索>的姊妹篇.在这 ...
- Android之系统架构
Android 是Google开发的基于Linux平台的开源手机操作系统.它包括操作系统.用户界面和应用程序 —— 移动电话工作所需的全部软件,而且不存在任何以往阻碍移动产业创新的专有权障碍.Andr ...
- 【PaPaPa】系统架构搭建浅析 - 人人可以搭架构
声明 [PaPaPa]这个项目是以技术分享与研究为目的而做的,并非商业项目,所以更多的是提供一种思路,请勿直接在项目中使用. 上一篇隐藏开源项目地址实属无奈,为了寻找一起做这件事的同伴不得已刷了一天推 ...
- Android 笔记之 Android 系统架构
Android笔记之Android系统架构 h2{ color: #4abcde; } a{ color: blue; text-decoration: none; } a:hover{ color: ...
- Dubbo入门到精通学习笔记(七):基于Dubbo的分布式系统架构介绍(以第三方支付系统架构为例)、消息中间件的作用介绍
文章目录 架构简单介绍 消息中间件在分布式系统中的作用介绍 消息中间件的定义 消息中间件的作用 应用场景 JMS(Java Message Service) JMS消息模型 实现了JMS规范的消息中间 ...
- [开发笔记usbTOcan]系统架构设计
SYS.3 | 系统架构设计 系统架构设计过程的目的是建立一个系统体系结构设计,并确定哪些系统需求分配给系统的哪些元素,并根据确定的标准评估系统架构. 系统结构设计需要做一下工作: 开发系统架构设计. ...
- 汇总java生态圈常用技术框架、开源中间件,系统架构及经典案例等
转自:http://www.51testing.com/html/83/n-3718883.html 有人认为编程是一门技术活,要有一定的天赋,非天资聪慧者不能及也.非也,这是近几年,对于技术这碗饭有 ...
- 【Java进阶面试系列之一】哥们,你们的系统架构中为什么要引入消息中间件?
转: [Java进阶面试系列之一]哥们,你们的系统架构中为什么要引入消息中间件? **这篇文章开始,我们把消息中间件这块高频的面试题给大家说一下,也会涵盖一些MQ中间件常见的技术问题. 这里大家可以关 ...
随机推荐
- linux 文件系统管理三部曲之二:创建文件系统
创建文件系统的含义:就是格式化一个硬盘分区,不同的格式化方式,就是创建了不同的文件系统. 格式化: 低级格式化:划分分区前执行,主要是划分硬盘的磁道等. 高级格式化:划分分区后执行,创建文件系统 创建 ...
- R ggplot学习笔记1
R 可视化学习笔记 记参数挺费劲的,还是用的时候查官方文档吧,现在记个大概就行吧~ 1.ggplot2分层次绘图 1.1 核心理念 把绘图与数据分离,把数据相关的绘图与数据无关的绘图分离,按图层作图. ...
- excel给一列数据添加前缀和后缀
1.选中一列单元格后设置单元格格式,在自定义中输入-----“前缀”@(前缀为需要添加的内容) 输入----@“后缀” 2.字符串拼接:“前缀”&B1,B1&“后缀”
- 论文阅读笔记(十一)【ICCV2017】:Jointly Attentive Spatial-Temporal Pooling Networks for Video-based Person Re-Identification
Introduction (1)Motivation: 当前采用CNN-RNN模型解决行人重识别问题仅仅提取单一视频序列的特征表示,而没有把视频序列匹配间的影响考虑在内,即在比较不同人的时候,根据不同 ...
- 题解 P5718 【【深基4.例2】找最小值】
题目传送门 思路 介绍一种新方法--sort排序,它的格式是这样的sort(a+1,a+n+1,cmp);,我们只需要把a数组排好序,然后输出第\(1\)个元素即可. 定义a数组与变量\(n\)并输入 ...
- (1)-Android学习笔记之:初识Android系统架构和项目结构
Android系统架构 Android程序结构 创建一个Android项目,为初学便于理解,将程序项目结构切换为Project模式,项目结构如下 .gradle和.idea:这两个目录下放的都是And ...
- java中拦截器与过滤器
注:文摘自网络,仅供自己参考 1.首先要明确什么是拦截器.什么是过滤器 1.1 什么是拦截器: 拦截器,在AOP(Aspect-Oriented Programming)中用于在某个方法或字段被访问之 ...
- yii2表单提交CSRF验证
Yii2表单提交默认需要验证CSRF,如果CSRF验证不通过,则表单提交失败,解决方法如下: 第一种解决办法是关闭Csrf public $enableCsrfValidation = false; ...
- 想要学好Git,应该掌握哪些基础知识?
说到Git,作为程序员的你,在项目开发中一定会使用到或将来也一定会使用到的,但是我相信,很多在使用Git的人,都只是停留一些简单的操作上,比如提交(commit).拉取(pull).推送(push). ...
- C#简单鼠标键盘钩子KMHook
简介:由三个文件构成Pinvo.cs.KeyboardHook.cs.MouseHook.cs Pinvo.cs 是KeyboardHook与MouseHook需要的一些常量消息的定义 Keyboar ...