1.2 架构
从概念上来说,所有的计算都符合“数据输入—处理转换—数据输出”的过程,这个过程有时候叫作数据处理流水线(Pipeline),流水线的概念来自生产制造中的流水线。以WordCount为例,其处理过程抽象如图1-1所示。
图1-1 Flink WordCount处理过程抽象
图1-1中,Source表示数据输入;转换表示数据处理的过程,在处理转换中会包含1个或者多个计算步骤;Sink表示数据输出。Source、Sink合并起来就是IO。无论是Source、Sink还是中间的转换,在Flink中都统一抽象为Transformation。
随着数据量越来越大,远远超过了单机的处理能力,作业需要在一个几十上百台的集群上执行,这时候就涉及如何将作业横向和纵向拆分。横向拆分是将作业中的步骤并行执行,用并行度(Parallism)来表示一个步骤有多少个实例并行执行。纵向拆分是将作业的步骤进行拆分,拆分出来的每一个实体叫作Task,每个Task最终会分配到一台服务器上执行,最终形成一个由Task组成的有向无环图(DAG),Task中执行1个或者多个算子的示例如图1-2所示。
图1-2 Flink作业的Task DAG示例
从DAG中可以看到,Source的并行度为1,所以其只有1个Task。FlatMap的并行度为2,所以其有2个Task。KeyedAgg与Sink根据优化策略合并成了1个执行单元,并行度都是2,所以有2个Task。KeyedAgg与Sink的合并使用了算子融合,将符合优化策略的计算步骤合并成为一个OperatorChain,具体内容后边章节会阐述。
1.2.1 技术架构
Flink是一个批流一体的分布式计算引擎,作为一个分布式计算引擎,必须提供面向开发人员的API,根据业务逻辑开发Flink作业,作业除了包含业务逻辑外,还需要跟外部的数据存储进行交互。作业开发、测试完毕后,交给Flink集群进行执行,同时还要让运维人员能够管理与监控Flink。
Flink技术架构如图1-3所示。
图1-3 Flink技术架构
对于应用开发者而言,直接使用API层和应用框架层,两者的差别在于API的层次不同,API层是Flink对外提供的核心API,应用框架层是在核心API之上提供的面向特定计算场景、更加易用的API。
1.应用框架层
该层也可以称为Flink应用框架层,是指根据API层的划分,在API层之上构建的满足特定应用场景的计算框架,总体上分为流计算和批处理两类应用框架。面向流计算的应用框架有流上SQL(Flink Table&SQL)、CEP(复杂事件处理),面向批处理的应用框架有批上SQL(Flink Table&SQL)、Flink ML(机器学习)、Gelly(图处理)。
(1)Table&SQL
Table&SQL是Flink中提供SQL语义支持的内置应用框架,其中Table API提供Scala和Java语言的SQL语义支持,允许开发者使用编码的方式实现SQL语义。SQL基于Apache Calcite,支持标准SQL,使用者可以在应用中直接使用SQL语句,同时也支持Table API和SQL的混合编码。
Table API和SQL在流计算和批处理上提供了一致的接口,批处理和流式传输的Table API和SQL程序都遵循相同的模式。
两者在底层上都依赖于Apache Calcite提供的优化能力,借助Apache Calcite内置的优化规则,加上Flink实现的分布式流、批优化规则,在逻辑和物理两个层面上进行优化。
(2)CEP
CEP本质上是一种实时事件流上的模式匹配技术,是实时事件流上常见的用例。CEP通过分析事件间的关系,利用过滤、关联、聚合等技术,根据事件间的时序关系和聚合关系制定匹配规则,持续地从事件流中匹配出符合要求的事件序列,通过模式组合能够识别更加复杂的事件序列,主要用于反欺诈、风控、营销决策、网络安全分析等场景。
常见的开源CEP引擎有Esper、Siddhi、Drools等,商业CEP引擎有Esper企业版、StreamBase、StreamInsight等。其中,Esper是成熟且资历比较老的CEP引擎,在金融行业的应用比较广泛,开源Esper支持单机版,Esper企业版支持双机热备。
现有的复杂事件处理引擎除Siddhi支持分布式部署之外(依赖Storm),其余的复杂事件处理引擎都存在分布式计算支持不够的问题。Flink CEP应用开发框架借助Flink的分布式计算引擎,提供了复杂事件处理API,能够实现完整的模式匹配语义,同时部分实现了SQL 2016标准中的SQL MatchRecognize语义,支持通过SQL定义复杂事件处理匹配规则。
(3)Gelly
Gelly是一个可扩展的图形处理和分析库。Gelly是在DataSet API之上实现的,并与DataSet API集成在一起。因此,它受益于其可扩展且强大的操作符。Gelly具有内置算法,如label propagation(标签传播)、triangle enumeration和page rank, 但也提供了一个自定义图算法实现的简化Graph API。
Gelly的应用不多,本书中不进行深入阐述,读者可参考官方文档进行了解。
(4)ML
Flink ML是Flink的机器学习框架,定位类似于Spark MLLib,但是在目前阶段其实现的算法和成熟度距离Spark MLLib有较大差距,不具备生产环境的可用性,在Flink1.9之后的版本中会对其进行重构。本书中不进行详细阐述,读者可参考官方文档进行了解。
2. API层
API层是Flink对外提供能力的接口,实现了面向流计算的DataStream API和面向批处理的DataSet API。理论上来说,Flink的API应该像Apache Beam、Spark那样实现API层流批统一,但是目前却依然是两套系统,使用起来并不方便,所以社区也在以DataStream API为核心,推进批流API的统一。DataSet API未来会被废弃,所以本书不会对基于DataSet的批处理方面进行过多的阐述。
3.运行时层
运行时层提供了支持Flink集群计算的核心,将开发的Flink应用分布式执行起来,包含如下内容。
1)DAG抽象:将分布式计算作业拆分成并行子任务,每个子任务表示数据处理的一个步骤,并且在上下游之间建立数据流的流通关系。
2)数据处理:包含了开发层面、运行层面的数据处理抽象,例如包含数据处理行为的封装、通用数据运算的实现(如Join、Filter、Map等)。
3)作业调度:调度批流作业的执行。
4)容错:提供了集群级、应用级容错处理机制,保障集群、作业的可靠运行。
5)内存管理、数据序列化:通过序列化,使用二进制方式在内存中存储数据,避免JVM的垃圾回收带来的停顿问题。
6)数据交换:数据在计算任务之间的本地、跨网络传递。
Flink运行时层并不是给一般的Flink应用开发者使用的。
4.部署层
该层是Flink集群部署抽象层,Flink提供了灵活的部署模式,可以本地运行、与常见的资源管理集群集成,也支持云上的部署。
Flink支持多种部署模式:
1)Standalone模式:Flink安装在普通的Linux机器上,或者安装在K8s中,集群的资源由Flink自行管理。
2)Yarn、Mesos、K8s等资源管理集群模式:Flink向资源集群申请资源,创建Flink集群。
3)云上模式:Flink可以在Google、亚马逊云计算平台上轻松部署。
5.连接器(Connector)
Connector是Flink计算引擎与外部存储交互的IO抽象,是前面提到过的Source和Sink的具体实现。在Connector的实现上,流和批的实现是两套系统,这属于历史遗留问题,未来会逐渐统一。
1.2.2 运行架构
通过技术架构来了解的Flink是静态的,而实际上Flink集群在运行的时候,存在不同的进程角色来完成集群的管理,作业的提交、执行、管理等一系列的动作,如图1-4所示。
Flink集群采用Master-Slave架构,Master的角色是JobManager,负责集群和作业管理,Slave的角色是TaskManager,负责执行计算任务。除此之外,Flink还提供了客户端来管理集群和提交任务,其中JobManager和TaskManager是集群的进程,Flink客户端是在集群外部执行的进程,不是集群的一部分。
1. Flink客户端
Flink客户端是Flink提供的CLI命令行工具,用来提交Flink作业到Flink集群,在客户端中负责Stream Graph(流图)和Job Graph(作业图)的构建,后面有详细介绍。使用Table API和SQL编写的Flink应用,还会在客户端中负责SQL解析和优化。
Flink的Flip改进建议中提出了新的模式,SQL解析、优化,StreamGraph、JobGraph、ExecutionGraph构建转换等全部都会在JobManager中完成,这将在Flink1.10后续版本中实现。
2. JobManager
JobManager根据并行度将Flink客户端提交的Flink应用分解为子任务,从资源管理器申请所需的计算资源,资源具备之后,开始分发任务到TaskManager执行Task,并负责应用容错,跟踪作业的执行状态,发现异常则恢复作业等。
图1-4 Flink运行时架构
3. TaskManager
TaskManager接收JobManager分发的子任务,根据自身的资源情况,管理子任务的启动、停止、销毁、异常恢复等生命周期阶段。
作业启动后开始从数据源消费数据、处理数据,并写入外部存储中。
无论使用哪种资源集群,以上所介绍的角色是必不可少的,其作用一样。
从图1-4中可以看到,JobManager是一个单点的部署模式,在Flink中支持JobManager的HA部署,在后续章节中会介绍Flink HA的部署。