热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

双维度剖析Flink整体架构

导读:从2014年开源到现在,Flink已经发展成一套非常成熟的大数据处理引擎,同时被很

点击上方“Python爬虫与数据挖掘”,进行关注

回复“书籍”即可获赠Python从入门到进阶共10本电子书

为学应须毕生力,攀高贵在少年时。

导读:从2014年开源到现在,Flink已经发展成一套非常成熟的大数据处理引擎,同时被很多公司作为流数据处理平台的底层技术。本文为大家介绍Flink的架构及其组成成分。


01
架构介绍


Flink系统架构主要分为APIs & LibrariesCoreDeploy三层,如图1所示,其中APIs层主要实现了面向流处理对应的DataStream API,面向批处理对应的DataSet API。Libraries层也被称作Flink应用组件层,是根据API层的划分,在API层之上构建满足了特定应用领域的计算框架,分别对应了面向流处理和面向批处理两类,其中面向流处理支持CEP(复杂事件处理)、基于类似SQL的操作(基于Table的关系操作);面向批处理支持Flink ML(机器学习库)、Gelly(图处理)。运行时层提供了Flink计算的全部核心实现,例如支持分布式Stream作业执行、JobGraph到ExecutionGraph的映射和调度等,为API层提供了基础服务。Deploy层支持多种部署模式,包括本地、集群(Standalone、YARN、Kubernetes)及云部署(GCE/EC2)。


图1 Flink整体架构



1、编程接口


Flink提供了多种抽象的编程接口,适用于不同层级的用户。数据分析人员和偏向业务的数据开发人员可以使用Flink SQL定义流式作业。如图2所示,Flink编程接口分为4层。


图2 Flink编程接口抽象




Flink SQL


一项大数据技术如果想被用户接受和使用,除了应具有先进的架构理念之外,另一点非常重要的就是要具有非常好的易用性。我们知道虽然Pig中的操作更加灵活和高效,但是在都满足数据处理需求的前提下,数据开发者更愿意选择Hive作为大数据处理的开发工具。其中最重要的原因是,Hive能够基于SQL标准进行拓展,提出了HQL语言,这就让很多只会SQL的用户也能够快速掌握大数据处理技术。因此Hive技术很快得到普及。


对于Flink同样如此,如果想赢得更多的用户,就必须不断增强易用性。FlinkSQL基于关系型概念构建流式和离线处理应用,使用户能够更加简单地通过SQL构建Flink作业。




Table API 


Flink SQL解析生成逻辑执行计划和物理执行计划,然后转换为Table之间的操作,最终转换为JobGraph并运行在集群上。Table API和Spark中的DataSet/DataFrame接口类似,都提供了面向领域语言的编程接口。相比Flink SQL,Table API更加灵活,既可以在Java & Scala SDK中与DataStream和DataSet API相互转换,也能结合Flink SQL进行数据处理。




DataStream & DataSet API


在早期的Flink版本中,DataSet API和DataStream API分别用于流处理和批处理场景。DataSet用于处理离线数据集,DataStream用于处理流数据集。DataFlow模型希望使用同一套流处理框架统一处理有界和无界数据,那么为什么Flink还要抽象出两套编程接口来处理有界数据集和无界数据集呢?这也是近年来Flink社区不断探讨的话题。目前Table和SQL API层面虽然已经能够做到批流一体,但这仅是在逻辑层面上的,最终还是会转换成DataSet API和DataStream API对应的作业。后期Flink社区将逐渐通过DataStream处理有界数据集和无界数据集,社区已经在1.11版本中对DataStream API中的SourceFunction接口进行了重构,使DataStream可以接入和处理有界数据集。在后期的版本中,Flink将逐步实现真正意义上的批流一体化。




Stateful Processing Function接口


Stateful Processing Function接口提供了强大且灵活的编程能力,在其中可以直接操作状态数据、TimeService等服务,同时可以注册事件时间和处理时间回调定时器,使程序能够实现更加复杂的计算。使用Stateful Processing Function接口需要借助DataStream API。虽然Stateful Processing Function接口灵活度很高,但是接口使用复杂度也相对较高,且在DataStream API中已经基于Stateful Process Function接口封装了非常丰富的算子,这些算子可以直接使用,因此,除非用户需要自定义比较复杂的算子(如直接操作状态数据等),否则无须使用Stateful Processing Function接口开发Flink作业。



2、运行时执行引擎


用户使用组件栈和接口编写的Flink作业最终都会在客户端转换成JobGraph对象,然后提交到集群中运行。除了任务的提交和运行之外,运行时还包含资源管理器Resource-Manager以及负责接收和执行Task的TaskManager,这些服务各司其职,相互合作。运行时提供了不同类型(有界和无界)作业的执行和调度功能,最终将任务拆解成Task执行和调度。同时,运行时兼容了不同类型的集群资源管理器,可以提供不同的部署方式,并统一管理Slot计算资源。



3、物理部署层


物理部署层的主要功能是兼容不同的资源管理器,如支持集群部署模式的Hadoop YARN、Kubernetes及Standalone等。这些资源管理器能够为在Flink运行时上运行的作业提供Slot计算资源。第4章会重点介绍Flink物理部署层的实现,帮助大家了解如何将运行时运行在不同的资源管理器上并对资源管理器提供的计算资源进行有效管理。




02
Flink集群架构


如图3所示,Flink集群主要包含3部分:JobManager、TaskManager和客户端,三者均为独立的JVM进程。Flink集群启动后,会至少启动一个JobManager和多个Task-Manager。客户端将任务提交到JobManager,JobManager再将任务拆分成Task并调度到各个TaskManager中执行,最后TaskManager将Task执行的情况汇报给JobManager。


图3 Flink集群架构图


客户端是Flink专门用于提交任务的客户端实现,可以运行在任何设备上,并且兼容Windows、macOS、Linux等操作系统,只需要运行环境与JobManager之间保持网络畅通即可。用户可以通过./bin/f?link run命令或Scala Shell交互式命令行提交作业。客户端会在内部运行提交的作业,然后基于作业的代码逻辑构建JobGraph结构,最终将JobGraph提交到运行时中运行。JobGraph是客户端和集群运行时之间约定的统一抽象数据结构,也就是说,不管是什么类型的作业,都会通过客户端将提交的应用程序构建成JobGraph结构,最后提交到集群上运行。


JobManager是整个集群的管理节点,负责接收和执行来自客户端提交的JobGraph。JobManager也会负责整个任务的Checkpoint协调工作,内部负责协调和调度提交的任务,并将JobGraph转换为ExecutionGraph结构,然后通过调度器调度并执行ExecutionGraph的节点。ExecutionGraph中的ExecutionVertex节点会以Task的形式在TaskManager中执行。


除了对Job的调度和管理之外,JobManager会对整个集群的计算资源进行统一管理,所有TaskManager的计算资源都会注册到JobManager节点中,然后分配给不同的任务使用。当然,JobManager还具备非常多的功能,例如Checkpoint的触发和协调等。


TaskManager作为整个集群的工作节点,主要作用是向集群提供计算资源,每个TaskManager都包含一定数量的内存、CPU等计算资源。这些计算资源会被封装成Slot资源卡槽,然后通过主节点中的ResourceManager组件进行统一协调和管理,而任务中并行的Task会被分配到Slot计算资源中。


根据底层集群资源管理器的不同,TaskManager的启动方式及资源管理形式也会有所不同。例如,在基于Standalone模式的集群中,所有的TaskManager都是按照固定数量启动的;而YARN、Kubernetes等资源管理器上创建的Flink集群则支持按需动态启动TaskManager节点。



03
核心概念


1、有状态计算


在Flink架构体系中,有状态计算是非常重要的特性之一。如图4所示,有状态计算是指在程序计算过程中,程序内部存储计算产生的中间结果,并将其提供给后续的算子进行计算。状态数据可以存储在本地内存中,也可以存储在第三方存储介质中,例如Flink已经实现的RocksDB。


图4 有状态处理和无状态处理


和有状态计算不同,无状态计算不会存储计算过程中产生的结果,也不会将结果用于下一步计算。程序只会在当前的计算流程中执行,计算完成就输出结果,然后接入下一条数据,继续处理。


无状态计算实现的复杂度相对较低,实现起来也比较容易,但是无法应对比较复杂的业务场景,例如处理实时CEP问题,按分钟、小时、天进行聚合计算,求取最大值、均值等聚合指标等。如果不借助Flink内部提供的状态存储,一般都需要通过外部数据存储介质,常见的有Redis等键值存储系统,才能完成复杂指标的计算。


和Storm等流处理框架不同,Flink支持有状态计算,可以应对更加复杂的数据计算场景。



2、时间概念与水位线机制


在DataFlow模型中,时间会被分为事件时间和处理时间两种类型。如图5所示,Flink中的时间概念基本和DataFlow模型一致,且Flink在以上两种时间概念的基础上增加了进入时间(ingestion time)的概念,也就是数据接入到Flink系统时由源节点产生的时间。


图5 Flink时间概念


事件时间指的是每个事件在其生产设备上发生的时间。通常在进入Flink之前,事件时间就已经嵌入数据记录,后续计算从每条记录中提取该时间。基于事件时间,我们可以通过水位线对乱序事件进行处理。事件时间能够准确地反映事件发生的先后关系,这对流处理系统而言是非常重要的。在涉及较多的网络传输时,在传输过程中不可避免地会发生数据发送顺序改变,最终导致流系统统计结果出现偏差,从而很难通过实时计算的方式得到正确的统计结果。


处理时间是指执行相应算子操作的机器系统时间。当应用基于处理时间运行时,所有基于时间的算子操作(如时间窗口)将使用运行相应算子机器的系统时钟。例如,应用程序在上午9:15运行,则第一个每小时处理时间窗口包括在上午9:15到上午10:00之间处理的事件,下一个窗口包括在上午10:00到11:00之间处理的事件。


处理时间是最简单的时间概念,不需要在流和机器之间进行协调,它提供了最佳的性能和最低的延迟。但在分布式和异步环境中,处理时间不能提供确定性,因为它容易受到记录到达系统的速度(例如从消息队列到达系统)以及系统内算子之间流动速度的影响。


接入时间是指数据接入Flink系统的时间,它由SourceOperator自动根据当前时钟生成。后面所有与时间相关的Operator算子都能够基于接入时间完成窗口统计等操作。接入时间的使用频率并不高,当接入的事件不具有事件时间时,可以借助接入时间来处理数据。


相比于处理时间,接入时间的实现成本较高,但是它的数据只产生一次,且不同窗口操作可以基于统一的时间戳,这可以在一定程度上避免处理时间过度依赖处理算子的时钟的问题。


不同于事件时间,接入时间不能完全刻画出事件产生的先后关系。在Flink内部,接入时间只是像事件时间一样对待和处理,会自动分配时间戳和生成水位线。因此,基于接入时间并不能完全处理乱序时间和迟到事件。


- END -


本文摘编于《Flink设计与实现:核心原理与源码解析》。



推荐阅读:Flink贡献者/第四范式AI数据平台架构师张利兵撰写,源码剖析Flink设计思想、架构原理以及各模块实现原理,大量架构图、UML图。

送书
本周赠书:《Flink设计与实现:核心原理与源码解析
最后给大家推荐一个数据分析的直播,明天晚上8点,假期也记得给自己加油噢!

活动规则


参与方式:在下方公众号后台回复 “送书”关键字,记得是送书二字哈,即可参与本次的送书活动。

公布时间:2021年8月25号(周三)晚上20点

领取事宜:请小伙伴添加小助手微信: pycharm1314,或者扫码添加好友。添加小助手的每一个人都可以领取一份Python学习资料,更重要的是方便联系。

注意事项一定要留意微信消息,如果你是幸运儿就尽快在小程序中填写收货地址、书籍信息。一天之内没有填写收货信息,送书名额就转给其他人了噢,欢迎参与。

------------------- End -------------------

往期精彩文章推荐:

  • 盘点Python编程的简易版自动化工具——ADB史上全操作

  • 手机自动化测试IDE-----Airtest实战篇

  • 手机自动化测试IDE ----- 手把手教你用Airtest模拟器来连接手机

  • 手机自动化测试IDE-----Airtest基本操作方法




推荐阅读
  • [译]技术公司十年经验的职场生涯回顾
    本文是一位在技术公司工作十年的职场人士对自己职业生涯的总结回顾。她的职业规划与众不同,令人深思又有趣。其中涉及到的内容有机器学习、创新创业以及引用了女性主义者在TED演讲中的部分讲义。文章表达了对职业生涯的愿望和希望,认为人类有能力不断改善自己。 ... [详细]
  • Android Studio Bumblebee | 2021.1.1(大黄蜂版本使用介绍)
    本文介绍了Android Studio Bumblebee | 2021.1.1(大黄蜂版本)的使用方法和相关知识,包括Gradle的介绍、设备管理器的配置、无线调试、新版本问题等内容。同时还提供了更新版本的下载地址和启动页面截图。 ... [详细]
  • 本文介绍了Python爬虫技术基础篇面向对象高级编程(中)中的多重继承概念。通过继承,子类可以扩展父类的功能。文章以动物类层次的设计为例,讨论了按照不同分类方式设计类层次的复杂性和多重继承的优势。最后给出了哺乳动物和鸟类的设计示例,以及能跑、能飞、宠物类和非宠物类的增加对类数量的影响。 ... [详细]
  • 背景应用安全领域,各类攻击长久以来都危害着互联网上的应用,在web应用安全风险中,各类注入、跨站等攻击仍然占据着较前的位置。WAF(Web应用防火墙)正是为防御和阻断这类攻击而存在 ... [详细]
  • Java序列化对象传给PHP的方法及原理解析
    本文介绍了Java序列化对象传给PHP的方法及原理,包括Java对象传递的方式、序列化的方式、PHP中的序列化用法介绍、Java是否能反序列化PHP的数据、Java序列化的原理以及解决Java序列化中的问题。同时还解释了序列化的概念和作用,以及代码执行序列化所需要的权限。最后指出,序列化会将对象实例的所有字段都进行序列化,使得数据能够被表示为实例的序列化数据,但只有能够解释该格式的代码才能够确定数据的内容。 ... [详细]
  • Android中高级面试必知必会,积累总结
    本文介绍了Android中高级面试的必知必会内容,并总结了相关经验。文章指出,如今的Android市场对开发人员的要求更高,需要更专业的人才。同时,文章还给出了针对Android岗位的职责和要求,并提供了简历突出的建议。 ... [详细]
  • 20211101CleverTap参与度和分析工具功能平台学习/实践
    1.应用场景主要用于学习CleverTap的使用,该平台主要用于客户保留与参与平台.为客户提供价值.这里接触到的原因,是目前公司用到该平台的服务~2.学习操作 ... [详细]
  • Python开源库和第三方包的常用框架及库
    本文介绍了Python开源库和第三方包中常用的框架和库,包括Django、CubicWeb等。同时还整理了GitHub中最受欢迎的15个Python开源框架,涵盖了事件I/O、OLAP、Web开发、高性能网络通信、测试和爬虫等领域。 ... [详细]
  • 本文讨论了如何使用GStreamer来删除H264格式视频文件中的中间部分,而不需要进行重编码。作者提出了使用gst_element_seek(...)函数来实现这个目标的思路,并提到遇到了一个解决不了的BUG。文章还列举了8个解决方案,希望能够得到更好的思路。 ... [详细]
  • RN即ReactNative基于React框架针对移动端的跨平台框架,在学习RN前建议最好熟悉下html,css,js,当然如果比较急,那就直接上手吧,毕竟用学习前面基础的时间,R ... [详细]
  •        在搭建Hadoop环境之前,请先阅读如下博文,把搭建Hadoop环境之前的准备工作做好,博文如下:       1、CentOS6.7下安装JDK,地址:http:b ... [详细]
  • 本文由编程笔记#小编为大家整理,主要介绍了markdown纱线指挥相关的知识,希望对你有一定的参考价值。 ... [详细]
  • 谁说QLC闪存不堪大用!Intel 670p SSD深度揭秘
    ssd品牌众多,intel可以说是非常优秀的那一个,早些年的x25系列至今都是让人津津乐道的经典,不过近些年,intel固态存储的主要精力转向了企业、数据中心市场,消费级领域产品并 ... [详细]
  • 这篇文章主要讲解了“面向对象设计的六大原则是什么”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究 ... [详细]
  • 【图解HTTP】第一章 了解web及网络基础
    [图解HTTP]了解Web及网络基础Web页面是如何呈现的?根据Web浏览器地址栏中指定的URL,Web浏览器从Web服务器端获取文件资源(resour ... [详细]
author-avatar
mobiledu2502917073
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有