随着大数据时代的发展,海量数据和多种业务的实时处理需求激增,比如:实时监控报警系统、实时风控系统、实时推荐系统等,传统的批处理方式和早期的流式处理框架因其自身的局限性,难以在延迟性、吞吐量、容错能力以及使用便捷性等方面满足业务日益苛刻的要求。
在过去的几年里,从storm到后面spark的异军突起,面向数据时代的实时计算技术出现了很多。Flink自2019年初开源以来,以其独特的天然流式计算特性和更为先进的架构设计,极大地改善了以前的流式处理框架所存在的问题,迅速成为大数据实时计算领域炙手可热的技术框架,以及未来技术重要的发力点。
01 Flink简介
【什么是Flink】
Flink 是一个框架和分布式处理引擎,用于在无边界和有边界数据流上进行有状态的计算。Flink能在所有常见集群环境中运行,并能以内存速度和任意规模进行计算。使用官网的语句来介绍, Flink 就是 “Stateful Computations over Data Streams”。对于这句话,我们该怎么理解呢。
首先,Flink是一个纯流式的计算引擎,它的基本数据模型是数据流。流可以是无边界的无限流,即一般意义上的流处理。也可以是有边界的有限流,也就是批处理。因此 Flink 用一套架构同时支持了流处理和批处理。其次,Flink支持有状态的计算,稍微复杂一点的数据处理,比如说基本的聚合,数据流之间的关联都是有状态处理。
更直观的讲,对 Flink ⽽⾔,其所要处理的主要场景就是流数据,批数据只是流数据的⼀个极限特例⽽已,所以 Flink 是⼀款真正的流批统⼀的计算引擎。
【无界和有界数据】
**任何类型的数据都可以形成一种事件流。信用卡交易、传感器测量、机器日志、网站或移动应用程序上的用户交互记录,所有这些数据都形成一种流。数据可以被作为无界或者有界流来处理。 **
无界流 :有定义流的开始,但没有定义流的结束。它们会无休止地产生数据。无界流的数据必须持续处理,即数据被摄取后需要立刻处理。我们不能等到所有数据都到达再处理,因为输入是无限的,在任何时候输入都不会完成。处理无界数据通常要求以特定顺序摄取事件,例如事件发生的顺序,以便能够推断结果的完整性。
有界流: 有定义流的开始,也有定义流的结束。有界流可以在摄取所有数据后再进行计算。有界流所有数据可以被排序,所以并不需要有序摄取。有界流处理通常被称为批处理。
批处理:有界数据**
流处理:无界数据
Flink 擅长处理无界和有界数据集。精确的时间控制和状态化使得 Flink能够运行任何处理无界流的应用。有界流则由一些特殊设计的算法和数据结构进行内部处理,也产生了出色的性能。
【有状态计算】**
**有状态的计算:每次进行数据计算的时候基于之前数据的计算结果(状态)做计算,并且每次计算结果都会保存到存储介质中,计算关联上下文context 基于有状态的计算不需要将历史数据重新计算,提高了计算效率。
无状态的计算:每次进行数据计算只是考虑当前数据,不会使用之前数据的计算结果。**
【Flink 基石】
目前比较一致的观点是,Flink之所以能备受欢迎,离不开它最重要的四个基石:Checkpoint、State、Time、Window。**
首先是Checkpoint机制,这是 Flink 最重要的一个特性。Flink实现了分布式一致性的快照,从而提供了 exactly-once 的语义。在 Flink 之前的流计算系统都没有很好地解决这一问题。
每一个具有一定复杂度的流处理应用都是有状态的。提供了一致性的语义之后,Flink 为了让用户在编程时能够更轻松、更容易地去管理状态,引入了托管状态(managed state)并提供了 API 接口,让用户使用起来感觉就像在用Java 的集合类一样。
流处理的一个重要方面是应用程序如何衡量时间,即区分事件时间和处理时间。Flink 实现了 watermark 的机制,解决了基于事件时间处理时的数据乱序和数据迟到的问题。
最后,流计算中的计算一般都会基于窗口来计算,所以 Flink 提供了一套开箱即用的窗口操作,包括滚动窗口、滑动窗口、会话窗口,还支持非常灵活的自定义窗口以满足特殊业务的需求。
02 Flink核心架构
Flink 采用分层的架构设计,从而保证各层在功能和职责上的清晰。如图所示,自上而下分别是 API & Libraries 层、Runtime 核心层以及物理部署层:
【API & Libraries 层】
这一层主要提供了编程API和顶层类库:
编程 API : 用于进行流处理的 DataStream API 和用于进行批处理的 DataSet API。
顶层类库:包括用于复杂事件处理的库,用于结构化数据查询的 SQL & Table 库,以及基于批处理的机器学习库和图形处理库。
【Runtime 核心层】
这一层是 Flink 分布式计算框架的核心实现层,包括作业转换,任务调度,资源分配,任务执行等功能,基于这一层的实现,可以在流式引擎下同时运行流处理程序和批处理程序。
【 物理部署层】
Flink的物理部署层,用于支持在不同平台上部署应用。Flink 不仅可以运行在包括 YARN、Kubernetes 在内的多种资源管理框架上,还支持在裸机集群上独立部署。在启用高可用选项的情况下,它不存在单点失效问题。事实证明,Flink 已经可以扩展到数千核心,其状态可以达到 TB 级别,且仍能保持高吞吐、低延迟的特性。
03 Flink分层API
在上面介绍的 API & Libraries 这一层,Flink 又进行了更为具体的划分。
按照如图所示的层次结构,API 的一致性由下至上依次递增,接口的表现能力由下至上依次递减,各层的核心功能如下:
【SQL & Table API】
Flink 提供的最高层级的抽象是 SQL 。
Flink 支持两种关系型的 API,Table API 和 SQL。这两个 API 都是批处理和流处理统一的 API,意味着在无边界的实时数据流和有边界的历史记录数据流上,关系型 API 会以相同的语义执行查询,并产生相同的结果。支持用户自定义的标量函数,聚合函数以及表值函数,可以满足多样化的查询需求。
【DataStream API】
DataStream & DataSet API 是 Flink 数据处理的核心 API,支持使用Java或Scala语言进行调用,提供了数据读取,数据转换和数据输出等一系列常用操作的封装。
DataStream API 为许多通用的流处理操作提供了处理原语。这些操作包括窗口、逐条记录的转换操作,在处理事件时进行外部数据库查询等,并预先定义了例如map()、reduce()、aggregate()等函数。你可以通过扩展实现预定义接口或使用lambda 表达式实现自定义的函数。
【ProcessFunction】
ProcessFunction 是 Flink 所提供的最具表达力的接口,可以处理一或两条输入数据流中的单个事件,或者归入一个特定窗口内的多个事件。它提供了对于时间和状态的细粒度控制。开发者可以在其中任意地修改状态, 实现许多有状态的事件驱动应用所需要的、基于单个事件的复杂业务逻辑。
04 Flink核心组件
Flink 核心架构的第二层是 Runtime 层,该层包含了两个重要角色,分别是JobManager和TaskManager,是一个典型的Master-Slave架构。JobManager相当于是Master,TaskManager相当于是Slave。它们的功能分别如下:
(一)JobManager(JVM进程)
负责整个集群的资源管理与任务调度,在一个集群中只能有一个正在工作(active)的 JobManager,如果HA集群,那么其他JobManager是standby状态。
(1)资源管理。集群启动,TaskManager会将当前节点的资源信息注册给JobManager,所有TaskManager全部注册完毕,集群启动成功,此时JobManager会根据集群中的资源情况,为当前的Application分配TaskSlot资源。
(2)任务调度。分发task到TaskSlot中运行,Job执行过程中,JobManager会根据设置的策略触发checkpoint,任务执行完毕,JobManager会将Job执行的信息反馈给client,并且释放资源。
(二)TaskManager(JVM进程)
(1)负责当前节点上的任务运行及资源管理,TaskManager资源通过TaskSlot进行了划分,每个TaskSlot代表的是一份固定资源。例如,具有三个slots 的TaskManager会将其管理的内存资源分成三等份给每个 slot。
(2)负责TaskManager之间的数据交换。
05 Flink应用场景
世界各地有很多要求严苛的流处理应用都运行在 Flink 之上。接下来我们介绍常见的几类应用,分别是:事件驱动型应用,数据分析应用以及数据管道应用。
【事件驱动型应用】
事件驱动型应用是一类具有状态的应用,它从一个或多个事件流提取数据,并根据到来的事件触发计算、状态更新或其它外部动作。
在传统架构中,应用需要读写远程事务型数据库。相反,事件驱动型应用是在计算存储分离的传统应用基础上进化而来,是基于状态化流处理来完成。在该设计中,数据和计算不会分离,应用只需访问本地(内存或磁盘)即可获取数据。系统容错性的实现依赖于定期向远程持久化存储写入checkpoint。下图描述了传统应用和事件驱动型应用架构的区别。
事件驱动型应用无须查询远程数据库,本地数据访问使得它具有更高的吞吐和更低的延迟。典型的应用实例:反欺诈,异常检测,基于规则的报警以及业务流程监控等。
【数据分析应用】
数据分析任务需要从原始数据中提取有价值的信息和指标。传统的分析方式通常是利用批查询,或将事件记录下来并基于此构建应用来完成。为了得到最新数据的分析结果,必须先将它们加入分析数据集并重新执行查询或运行应用,随后将结果写入存储系统。
借助一些先进的流处理引擎,还可以实时地进行数据分析。和传统模式下读取有限数据集不同,流式查询会接入实时事件流,并随着事件消费持续产生和更新结果。这些结果数据可能会写入外部数据库系统或以内部状态的形式维护。
如图所示,Flink为持续流式分析和批量分析都提供了良好的支持。具体而言,它内置的 SQL 接口,将批、流查询的语义统一起来。无论是在记录事件的静态数据集上还是实时事件流上,相同 SQL 查询都会得到一致的结果。典型的应用实例:电信网络质量监控,移动应用中的产品更新及实验评估分析,消费者技术中的实时数据即席分析以及大规模图分析等。
【数据管道应用】
提取-转换-加载(ETL)是一种在存储系统之间进行数据转换和迁移的常用方法。ETL 作业通常会周期性地触发,将数据从事务型数据库拷贝到分析型数据库或数据仓库。
数据管道和 ETL 作业的用途相似,都可以转换、丰富数据,并将其从某个存储系统移动到另一个。但数据管道是以持续流模式运行,而非周期性触发。因此它支持从一个不断生成数据的源头读取记录,并将它们以低延迟移动到终点。例如:数据管道可以用来监控文件系统目录中的新文件,并将其数据写入事件日志;另一个应用可能会将事件流物化到数据库或增量构建和优化查询索引。
和周期性 ETL 作业相比,持续数据管道可以明显降低将数据移动到目的端的延迟。此外,由于它能够持续消费和发送数据,因此用途更广,支持用例更多。很多常见的数据转换和增强操作可以利用 Flink 的接口及用户自定义函数解决。典型的应用实例:电子商务中的实时查询索引构建以及电子商务中的持续ETL等。
06 Flink优点及挑战
【Flink 的优点】
基于上面的介绍,总结一下 Flink 的优点:
1)Flink 是基于事件驱动 (Event-driven) 的应用,能够同时支持流处理和批处理,结合Watermark处理乱序数据;
2)同时支持高吞吐、低延迟、高性能;
3)基于内存的计算,能够保证高吞吐和低延迟,具有优越的性能表现;
4)支持精确一次 (Exactly-once) 语意,能够完美地保证一致性和正确性;
5)支持有状态计算,并且可以将状态存在内存或者 RocksDB;
6)分层 API ,能够满足各个层次的开发需求;
7)支持高可用配置,支持保存点机制,能够提供安全性和稳定性上的保证;
8)多样化的部署方式,支持本地,远端,云端等多种部署方案;
9)具有横向扩展架构,能够按照用户的需求进行动态扩容;
10)活跃度极高的社区和完善的生态圈的支持。
**【Flink面临的挑战】
**Flink目前流计算的模型已经相对比较成熟和领先,也经历了各个公司大规模生产的验证,属于大数据生态里的计算环节,只做计算,不做存储。但是在实际工作当中,你会发现往往单独用Flink是不够的。比如你的数据是从哪里读出来,计算完之后数据又将存到哪里,又怎么消费这些数据,如何利用Flink来完成某个垂直领域的特殊任务等等。
**与此同时,如果要用Flink要做其他一些场景(比如机器学习,交互式分析)就会比较复杂,用户体验上还有很大的提升空间。这些涉及到上下游,需要一个强大的生态圈来完成。这也正是Flink生态所面临的挑战。
-
传感器
+关注
关注
2551文章
51125浏览量
753752 -
数据
+关注
关注
8文章
7045浏览量
89061 -
分布式
+关注
关注
1文章
900浏览量
74518 -
大数据
+关注
关注
64文章
8892浏览量
137456
发布评论请先 登录
相关推荐
评论