Apache Flink® — Stateful Computations over Data Streams – Apache Flink-基于数据流的有状态计算。
Flink 是一个框架和分布式处理引擎,用于在无边界和有边界数据流上进行有状态的计算。Flink 能在所有常见集群环境中运行,并能以内存速度和任意规模进行计算。
从上图中可以看出:
(1)Flink不仅可以处理实时的数据,也可以处理数据库、文件系统以及键值存储系统中的数据。Flink可以处理的数据类型是非常丰富的。
(2)Flink处理完数据之后,会将数据存储到HDFS、S3、NFS等存储系统中。同时,Flink也可以部署在k8s、Yarn、Mesos等多种资源管理器中运行。
(3)此外,Flink处理完数据之后,可以将数据传给下一个应用进行处理,也可以将数据写入日志中。还可以存储到数据库、文件系统以及键值存储系统中。
接下来,我们来介绍一下 Flink 架构中的重要方面。
任何类型的数据都可以形成一种事件流。信用卡交易、传感器测量、机器日志、网站或移动应用程序上的用户交互记录,所有这些数据都形成一种流。
数据可以被作为有边界或者无边界的流来处理。
无界数据流:无界数据流有一个开始但是没有结束,它们不会在生成时终止并提供数据,必须连续处理无界流,也就是说必须在获取后立即处理event。对于无界数据流我们无法等待所有数据都到达,因为输入是无界的,并且在任何时间点都不会完成。处理无界数据通常要求以特定顺序(例如事件发生的顺序)获取event,以便能够推断结果完整性。
有界数据流:有界数据流有明确定义的开始和结束,有界流可以在摄取所有数据后再进行计算。处理有界流不需要有序获取,因为可以对有界数据集进行排序。有界流的处理也称为批处理。
无界数据流和有界数据流都可以使用Flink进行处理,对应的就是流处理和批处理。 这种以流为世界观的架构,获得的最大好处就是具有极低的延迟。
Flink擅长处理无边界和有边界的数据集。对时间和状态的精确控制使得Flink运行时能够在无界数据流上运行任何类型的应用程序。有界流由专门为固定大小的数据集设计的算法和数据结构在内部处理,从而产生优异的性能。
可以通过在Flink上构建用例加深理解。
Flink是一个分布式系统,它需要计算资源来只从应用程序。Flink集成了所有常见的集群资源管理器,例如Hadoop YARN, Apache Mesos, and Kubernetes,但是同样可以作为独立集群运行。
Flink被设计为能够很好地工作于前面列出的每个资源管理器上,这是通过资源管理器特定的部署模式实现的。该部署模式允许Flink 可以采用与当前资源管理器相适应的方式进行交互。
在部署Flink应用程序时,Flink会根据应用程序配置的并行性自动识别所需的资源,并向资源管理器请求这些资源。在发生故障的情况下,Flink通过请求新的资源来替换发生故障的容器。所有提交或控制应用程序的所有通信都是通过 REST 调用进行的。这可以简化 Flink 与各种环境中的集成。
Flink 旨在任意规模上运行有状态流式应用程序。因此,应用程序被并行化为可能数千个任务,这些任务分布在集群中并发执行。所以应用程序能够充分利用无尽的 CPU、内存、磁盘和网络 IO。此外, Flink 很容易维护非常大的应用程序状态。其异步和增量的检查点算法确保对处理延迟产生最小的影响,同时保证精确一次状态的一致性。
Flink用户分享了他们生产环境中一些令人印象深刻的扩展性数字:
有状态Flink应用程序针对本地状态访问进行了优化。任务状态始终保存在内存中,如果状态大小超过可用内存,则保存在访问效率高的磁盘数据结构中。因此,任务通过访问本地(通常在内存中)状态来执行所有计算,从而产生非常低的处理延迟。Flink 通过定期和异步地对本地状态进行持久化存储来保证故障场景下精确一次的状态一致性。
Flink是一个框架,用于对无界和有界数据流进行有状态计算。Flink在不同的抽象级别上提供多个api,并为常见用例提供专用库。
接下来,我们将介绍 Flink 所提供的简单易用、易于表达的API和库。
可以被流处理框架构建并执行的应用程序类型是由框架对 流、状态、时间的支持程度来决定的。接下来,我们将对上述这些流处理应用的基本组件逐一进行描述,并对 Flink 处理它们的方法进行细致描述。
显而易见,流是流处理的基本组成要素。但是,流具有不同的特征。这些特征决定流如何以及何时被处理。Flin是一个通用的处理框架,能够处理任意类型的数据流。
有界流和无界流:流可以是无界的或者有界的,例如,古典给大小的数据集。Flink 在无界的数据流处理上拥有诸多功能强大的特性,同时,也针对有界的数据流开发了专用的高效算子。
实时流和历史记录流:所有的数据都是以流的形式产生。有两种方式处理这些数据。一是,在数据生成的时候进行实时处理;二是,将流持久化到存储系统中(例如,文件系统或者对象存储),之后再进行处理。Flink 应用能够同时支持处理实时以及历史记录数据流。
只有在每一个单独的事件上进行转换操作的应用才不需要状态,换言之,每一个具有一定复杂度的流处理应用都是有状态的。任何运行基本业务逻辑的流处理应用都需要在一定时间内存储所接收的事件或中间结果,以供后续的某个时间点(例如收到下一个事件或者经过一段特定时间)进行访问并进行后续处理。
应用状态在Flink中是一等公民。Flink提供了许多状态管理相关的特性支持,其中包括:
时间是流应用程序的另外一个重要组成部分。因为每一个时间都发生在特性的时间点,所以大多数的事件流都有事件本身所固有的时间语义。此外,许多常见的流计算是基于时间的,例如窗口聚合、会话计算、模式检测和基于时间的join。流处理一个重要的要素是应用如何衡量时间,即区分事件事件( event-time)和处理事件(processing-time)。
Flink提供了一组丰富的与时间相关的特性。
Flink 根据抽象程度分层,提供了三种不同的 API。每一种 API 在简洁性和表达力上有着不同的侧重,并且针对不同的应用场景。
最底层级的抽象仅仅提供了有状态流,它将通过过程函数(Process Function)被嵌入到DataStream API中。底层过程函数(Process Function) 与 DataStream API 相集成,使其可以对某些特定的操作进行底层的抽象,它允许用户可以自由地处理来自一个或多个数据流的事件,并使用一致的容错的状态。除此之外,用户可以注册事件时间并处理时间回调,从而使程序可以处理复杂的计算。
实际上,大多数应用并不需要上述的底层抽象,而是针对核心API(Core APIs)进行编程,比如DataStream API(有界或无界流数据)以及DataSet API(有界数据集)。这些API为数据处理提供了通用的构建模块,比如由用户定义的多种形式的转换(transformations),连接(joins),聚合(aggregations),窗口操作(windows)等等。DataSet API 为有界数据集提供了额外的支持,例如循环与迭代。这些API处理的数据类型以类(classes)的形式由各自的编程语言所表示。
Table API 是以表为中心的声明式编程,其中表可能会动态变化(在表达流数据时)。Table API遵循(扩展的)关系模型:表有二维数据结构(schema)(类似于关系数据库中的表),同时API提供可比较的操作,例如select、project、join、group-by、aggregate等。Table API程序声明式地定义了什么逻辑操作应该执行,而不是准确地确定这些操作代码的看上去如何 。 尽管Table API可以通过多种类型的用户自定义函数(UDF)进行扩展,其仍不如核心API更具表达能力,但是使用起来却更加简洁(代码量更少)。除此之外,Table API程序在执行之前会经过内置优化器进行优化。
你可以在表与 DataStream/DataSet 之间无缝切换,以允许程序将 Table API 与 DataStream 以及 DataSet 混合使用。
Flink提供的最高层级的抽象是 SQL 。这一层抽象在语法与表达能力上与 Table API 类似,但是是以SQL查询表达式的形式表现程序。SQL抽象与Table API交互密切,同时SQL查询可以直接在Table API定义的表上执行。
Flink是一个框架,用于在有界和无界数据流上进行有状态计算。由于许多流应用程序被设计为以最小停机时间连续运行,因此流处理器必须提供出色的故障恢复,以及在应用程序运行期间进行监控和维护的工具。
Flink 非常注重流数据处理的可运维性。因此在这一小节中,我们将详细介绍 Flink 的故障恢复机制,并介绍其管理和监控应用的功能。
在分布式系统中,机器和处理故障是普遍存在的,为了保证服务能够7*24小时稳定运行,像Flink这样的流处理器故障恢复机制是必须要有的。显然,这不仅意味着要能在服务出现故障的时候能够重启服务,而且还要在发生故障发生时,保证能够持久化服务内部各个组件的当前状态,只有这样才能保证在故障恢复时候,服务能够继续正常运行,好像故障就没有发生过一样。
Flink通过几下多种机制维护应用可持续运行及其一致性:
支持关键业务服务的流应用程序是需要维护的。bug需要修复和改进,或开发新功能。然而,更新一个有状态流应用程序并不是简单的事。通常不能简单地停止应用程序并重新启动修复或改进的版本,因为不能失去当前流应用程序的状态信息。
Flink的保存点是一个独特而强大的特性,它解决了升级服务过程中记录流应用状态信息及其相关难题。保存点是应用程序状态的一致快照,因此非常类似于检查点。然而,与检查点相比,保存点需要手动触发,并且在应用程序停止时不会自动删除。保存点可用于启动状态兼容的应用程序并初始化其状态。保存点可以实现以下功能:
如其它应用服务一样,持续运行的流应用服务也需要监控及集成到一些基础设施资源管理服务中,例如一个组件的监控服务及日志服务等。监控服务有助于预测问题并提前做出反应,日志服务提供日志记录能够帮助追踪、调查、分析故障发生的根本原因。最后,便捷易用的访问控制应用服务运行的接口也是Flink的一个重要的亮点特征。