大数据计算引擎分为离线计算和实时计算,离线计算就是我们通常说的批计算,代表是Hadoop MapReduce、Hive等大数据技术。实时计算也被称作流计算,代表是Storm、Spark Streaming、Flink等大数据技术。
计算引擎也在不断更新迭代,下图展示的是每一代计算引擎的代表,从第一代的Hadoop MapReduce,到第二代的Spark,再到第三代的Flink技术,从批处理到微批,再到真正的流式计算。
实时计算:
实时计算是相对离线计算的概念,重要是时效性。举个例子,离线计算通常是天级别的计算任务,比如统计一天的新增用户,商品销量,销售收入等。但是实时计算是只要有事件发生,统计结果就会发生变化,比如有一个新用户注册登录了,那么新增用户数就发生了变化,商品只要新增一个销售,销量就会发生变化,销售收入也会变化。所以实时计算能够更及时了解我们的现状,以及根据实时的统计结果做出决策,决策也更加具有时效性。
1. Flink介绍
Apache Flink是一个开源的流处理框架,应用于分布式、高性能、高可用的数据流应用程序。可以处理有限数据流和无限数据,即能够处理有边界和无边界的数据流。无边界的数据流就是真正意义上的流数据,所以Flink是支持流计算的。有边界的数据流就是批数据,所以也支持批处理的。不过Flink在流处理上的应用比在批处理上的应用更加广泛,统一批处理和流处理也是Flink目标之一。Flink可以部署在各种集群环境,可以对各种大小规模的数据进行快速计算。
随着大数据技术在各行各业的广泛应用,要求能对海量数据进行实时处理的需求越来越多,同时数据处理的业务逻辑也越来越复杂,传统的批处理方式和早期的流式处理框架也越来越难以在延迟性、吞吐量、容错能力以及使用便捷性等方面满足业务日益苛刻的要求。其中流式计算的典型代表是Storm和Flink技术。它们数据处理的延迟都是亚秒级低延迟,但是Flink相比Storm还有其他的一些优势,比如支持exactly once语义,确保数据不会重复。 Storm支持at least once语义,保证数据不会丢失。保证数据不会重复的代价很高,比如数据下游操作属于幂等操作。另外从测试结果来看,Flink在低延迟的基础上还能保证高吞吐,优势明显。
在这种形势下,新型流式处理框架Flink通过创造性地把现代大规模并行处理技术应用到流式处理中来,极大地改善了以前的流式处理框架所存在的问题。
2. Flink发展
诞生于2009年,原来叫StratoSphere,是柏林工业大学的一个研究性项目,早期专注于批计算。
2014年孵化出Flink并捐给Apache
2014 年 8 月,Flink 第一个版本 0.6 正式发布(至于 0.5 之前的版本,那就是在
Stratosphere 名下的了)。与此同时 Fink 的几位核心开发者创办了 Data Artisans 公司,主要做 Fink 的商业应用,帮助企业部署大规模数据处理解决方案。
2014 年 12 月,Flink 项目完成了孵化,一跃成为 Apache 软件基金会的顶级项目。
2015 年 4 月,Flink 发布了里程碑式的重要版本 0.9.0,很多国内外大公司也正是从这时开始关注、并参与到 Flink 社区建设的。
2019 年 1 月,长期对 Flink 投入研发的阿里巴巴,以 9000 万欧元的价格收购了 Data Artisans 公司;之后又将自己的内部版本 Blink 开源,继而与 8 月份发布的 Flink 1.9.0版本进行了合并。自此之后,Flink 被越来越多的人所熟知,成为当前最火的新一代大数据处理框架。
3. Flink在企业中的应用
Flink 为全球许多公司和企业的关键业务应用提供了强大的支持。
对于数据处理而言,任何行业、任何公司的需求其实都是一样的:数据规模大、实时性要求高、确保结果准确、方便扩展、故障后可恢复——而这些要求,作为新一代大数据流式处理引擎的 Flink 统统可以满足!这也正是 Flink 在全世界范围得到广泛应用的原因。
4. Flink的核心特性
Flink的核心特性:
- 高吞吐和低延迟:每秒处理数百万个事件,毫秒级延迟。
- 结果的准确性:Flink 提供了事件时间(event-time)和处理时间(processing-time)语义。对于乱序事件流,事件时间语义仍然能提供一致且准确的结果。
- 精确一次(exactly-once)的状态一致性保证。
- 可以连接到最常用的存储系统,如 Apache Kafka、Apache Cassandra、Elasticsearch、JDBC、Kinesis 和(分布式)文件系统,如 HDFS 和 S3。
- 高可用:本身高可用的设置,加上与 K8s,YARN 和 Mesos 的紧密集成,再加上从故障中快速恢复和动态扩展任务的能力,Flink 能做到以极少的停机时间 7×24 全天候运行。
- 能够更新应用程序代码并将作业(jobs)迁移到不同的 Flink 集群,而不会丢失应用程序的状态。
除此之外,还有
4.1 分层API
Flink 还是一个非常易于开发的框架,因为它拥有易于使用的分层 API,整体 API 分层如图所示:
有状态流处理:
最底层级的抽象仅仅提供了有状态流,它将处理函数( Process Function)嵌入到了DataStream API 中。底层处理函数(Process Function)与 DataStream API 相集成,可以对某些操作进行抽象,它允许用户可以使用自定义状态处理来自一个或多个数据流的事件,且状态具有一致性和容错保证。除此之外,用户可以注册事件时间并处理时间回调,从而使程序可以处理复杂的计算。
DataStream / Dataset API
大多数应用并不需要上述的底层抽象,而是直接针对核心 API(Core APIs) 进行编程,比如 DataStream API(用于处理有界或无界流数据)以及 DataSet API(用于处理有界数据集)。这些 API 为数据处理提供了通用的构建模块,比如由用户定义的多种形式的转换(transformations)、连接(joins)、聚合(aggregations)、窗口(windows)操作等。DataSet API为有界数据集提供了额外的支持,例如循环与迭代。这些 API 处理的数据类型以类(classes) 的形式由各自的编程语言所表示。
Table API
Table API 是以表为中心的声明式编程,其中表在表达流数据时会动态变化。Table API 遵循关系模型:表有二维数据结构(schema)(类似于关系数据库中的表),同时 API 提供可比较的操作,例如 select、join、group-by、aggregate 等。
SQL:
Flink 提供的最高层级的抽象是SQL。这一层抽象在语法与表达能力上与 Table API 类似, 但是是以 SQL 查询表达式的形式表现程序。SQL 抽象与Table API 交互密切,同时 SQL 查询可以直接在 Table API 定义的表上执行。
目前 Flink SQL 和Table API 还在开发完善的过程中,很多大厂都会二次开发符合自己需要的工具包。而 DataSet 作为批处理API 实际应用较少,2020 年 12 月 8 日发布的新版本 1.12.0,已经完全实现了真正的流批一体,DataSet API 已处于软性弃用(soft deprecated)的状态。用Data Stream API 写好的一套代码, 即可以处理流数据, 也可以处理批数据,只需要设置不同的执行模式。这与之前版本处理有界流的方式是不一样的,Flink 已专门对批处理数据做了优化处理。
4.2. 处理无界和有界数据
任何数据都可以形成一种事件流。银行卡(信用卡)交易、传感器测量、机器日志、网站或移动应用程序上的用户交易记录等等,所有这些数据都能形成一种流。
数据可以被作为无界和有界流来处理。
无界流
- 无界流:有定义流的开始,但是没有定义流的结束,会无休止地产生数据。处理无界数据通常要求以特定顺序摄取事件,例如事件发生的顺序,以便能够推断结果的完整性。
有界流
- 有界流:有定义流的开始,也有定义流的结束。有界流所有数据可以被排序,所以并不需要有序提取。有界流通常被称为批处理。
Apache Flink 擅长处理无界和有界数据集。对时间和状态的精确控制使 Flink 的运行时能够在无限流上运行任何类型的应用程序。有界流由专门为固定大小的数据集设计的算法和数据结构在内部进行处理,从而产生出色的性能。
5. Flink vs SparkStreaming
5.1 流(Stream)和微批处理(micro-streaming)
5.2 数据模型
- Flink的基本数据模型是数据流和事件序列。
- Spark采用的是RDD模型,从本质上说SparkStreaming的DStream实际上是一组一组的小批量数据RDD集合。
5.3 运行时架构
- Flink是标准的流执行模式,一个事件在一个节点处理完之后,可以直接发往下一个节点进行处理。
- SparkStreaming是微批计算,将DAG分成一个个不同的Stage,一个完成之后才可以进行下一个。
6. Flink应用场景
Flink的功能强大,它的主要特性包括:流批一体化、精确的状态管理、事件时间支持以及精确的状态一次性保证等。Flink不仅仅可以在Yarn、Mesos、Kubernetes上面运行,同时也支持在裸机机器上运行。在启用高可用选项的情况下,并不存在单点失效问题。实践证明,在处理TB级别的数据时,Flink仍然能保持高吞吐、低延迟的特性。
6.1 事件驱动型应用
事件驱动型应用是一类具有状态的应用,从一个或者多个事件流中提取数据,并根据到来的事件触发计算、更新状态或者进行其他计算。事件驱动型应用是从计算存储分离的传统应用基础上演变而来的。在传统的架构中,需要通过读写事务型数据库来完成。
但是,事件驱动型应用是基于状态化流处理来完成;而且数据和计算不会分离,应用只需要访问本地(内存或磁盘)即可获取数据。通过定期持久化的写入checkpoint来进行系统容错。下图描述了传统应用和事件驱动型应用架构的区别。
6.1.1 事件驱动型应用的优势
- 事件驱动型应用通过本地数据访问(无需查询远程数据库),使得它具有更高的吞吐和更低的延迟。
- 因为通过异步、增量式地完成持久化存储checkpoint,这就保证了checkpoint对事件处理的影响很微小。
- 传统应用中,通常多个应用会共享一个数据库,因此对数据库的任何修改(调整IP、用户名/密码、扩容、升级)都需要谨慎协调。事件型应用只需要考虑自身数据,就不用考虑这些影响。
6.1.2 Flink如何支持事件驱动型应用
- Flink提供了一系列丰富的状态操作原语,能够保证精确一次的一致性语义处理TB级别的有状态数据。
- Flink还支持事件时间,可以自由地定制窗口逻辑。内置的ProcessFunction支持细粒度的时间控制。
- Flink具有复杂事件处理(CEP)类库,可以用来检测数据流中的模式。
- Flink的突出特点是SavePoint。SavePoint是一个一致性的状态映像,可以做兼容应用程序的起点。在完成一次SavePoint之后,即可进行应用的升级和扩容,还可以启动多个版本的应用来完成A/B测试。
6.1.3 事件驱动型应用的经典案例
- 反欺诈
- 异常检测
- 基于规则的报警
- 业务流程监控
- (社交网络)Web应用
6.2 数据分析应用
- 数据分析主要是需要从原始数据中提取有价值的数据和维度。传统的数据分析方式通常是利用批处理查询。为了能得到最新的数据分析结果,必须把数据实时加入到数据集市,随后将结果写入OLAP实时数据仓库或者生成数据分析报告。
- 借助一些先进的流式处理引擎,进行实时数据分析。和传统模式下读取有限数据集不同的是,流式查询会接入实时流,并随着事件消费持续产生和更新结果。
如下图所示,Flink同时支持流式及批量分析应用
6.2.1 流式分析应用的优势
- 和批量分析相比,由于流式分析省掉了周期性的数据导入和查询过程,因此流式数据分析的延迟更低。
- 批量查询必须处理那些有定期导入数据的边界,而流式处理不需要关注这个问题。
- 批量数据分析必须由多个独立组件组成,需要周期性地调度读取数据和统计数据。如此复杂的流水线操作起来比较繁琐,一旦某个组件出问题将会影响流水线的下游步骤。而流式分析的应用整体运行在Flink系统之上,涵盖了从数据接入到后续结果计算的所有步骤,Flink本身有故障恢复机制。
6.2.2 Flink如何支持数据分析类应用
Flink对流式数据分析和批量数据分析都提供了很好的支持。它内置了一个符合ANSI标准的SQL接口,能够将流、批查询的语义统一起来。同时,Flink还支持丰富的用户自定义函数,能够在SQL中执行自定义函数。Flink的DataStream API和DataSet API能够进行更底层的控制。而且,Flink的Gelly库为基于批量数据集的大规模高性能图分析提供了算法和构建模块支持。
6.2.3 数据分析应用的经典案例
- 电信网络质量监控
- 移动应用中的产品更新和实验评估分析
- 消费中心的实时数据即席分析
- 大规模图分析
6.3 数据管道应用
抽取-转换-加载(ETL)是传统数据仓库进行数据转换和迁移的常用方法。ETL通常会周期性的将数据从事务型数据库或者原始日志同步到分析型数据仓库中。
数据管道应用和ETL作业的用途相似,都可以转换、加工数据。并将其从某个存储系统移动到另一个。但数据管道是以持续流模式运行,而非周期性出发。数据管道支持从一个不断生成数据的源头读取记录,并且低延迟的将数据结果加载到终点。
下图描述了周期性ETL作业和持续数据管道的差异。
6.2.1 数据管道的优势
和周期性ETL作业相比,持续数据管道可以明显降低数据移动到目标端的延迟。
6.2.2 Flink如何支持数据管道应用
很多常见的数据转换和增强操作可以利用Flink的SQL接口(或者Table API)及用户自定义函数解决。如果数据管道有更高级的需求,可以选择更通用的DataStream API来实现。Flink为多种数据存储系统(例如:Kafka、Kinesis、Elasticsearch、JDBC数据库系统等)内置了连接器。它还具有用于文件系统的连续源,这些源监视目录和接收器以时间存储方式写入文件。
6.2.3 数据管道应用的经典案例
- 电子商务中的实时数据查询索引构建
- 电子商务中的持续ETL
7. 部署
Flink是一个分布式系统,它需要计算资源来执行应用程序。Flink集成了所有常见的集群资源管理器,例如Hadoop Yarn、Apache Mesos和Kubernetes,同时也可以作为独立集群运行。
8. 运行任意规模的应用
Flink通常把应用程序并行化数千个任务,这些任务分布在集群中并发执行。因此应用程序能够充分利用无尽的CPU、内存、磁盘和网络IO。Flink能够很方便的对应用程序的状态进行维护。其异步和增量的检查点算法仅仅会对数据延迟产生极小的影响。而且能够保证精确一次状态的一致性。
- 每天能处理数以万亿的数据
- 应用维护几TB大小的状态
- 应用在数千个内核上运行
9. 利用内存进行计算
有状态的 Flink 程序针对本地状态访问进行了优化。任务的状态始终保留在内存中,如果状态大小超过可用内存,则会保存在能高效访问的磁盘数据结构中。Flink 通过定期和异步地对本地状态进行持久化存储来保证故障场景下精确一次的状态一致性。