Apache Flink 是一个集众多具有竞争力的特性于一身的流处理引擎,是开发和运行多种不同类型应用程序的绝佳选择。Flink 提供了流处理和批处理支持、复杂的状态管理、事件时间处理语义以及状态的精确一次一致性保证等功能。此外,Flink 可以在多种资源管理框架上部署,比如 YARN 和 Kubernetes,也可以作为独立集群部署在裸机硬件上。Flink 的高可用配置确保了系统没有单点故障。实际上,Flink 能够扩展到数千个内核和 TB 级的应用状态,提供高吞吐量和低延迟,并为世界上一些要求最苛刻的流处理应用提供支持。

本文将介绍 Flink 支持的三类常见的有状态的流处理应用,分别为事件驱动型应用、数据管道应用和数据分析应用。

注:这里为了突出有状态的流处理的用途之多,将不同应用的类别区分地很明显,而事实上大多数真实应用都会同时具有多种类别的特性。

事件驱动型应用

第一种应用类型是事件驱动型应用。事件驱动型应用程序是有状态的应用程序,它从一个或多个事件流中摄取事件,并通过触发计算、状态更新或执行外部操作来响应这些事件。事件驱动型应用本质上是传统应用程序的演变。传统的应用程序将计算层和数据存储层分离,在这种架构中,应用程序从远程事务数据库读取数据并将其持久化。

相比之下,事件驱动型应用程序是基于有状态的流处理应用的设计。在这种架构中,数据和计算存储在同一位置,因此可以进行本地(内存或磁盘)数据访问。容错性通过定期将检查点(checkpoint)写入远程持久化存储来实现。下图展示了传统应用程序架构和事件驱动型应用程序之间的区别。

image.png
事件驱动型应用程序有很多优势。它们不需要查询远程数据库,而是通过本地访问数据来获得更好的性能,不论是在吞吐量还是延迟方面。检查点对常规事件处理的影响非常小,因为它们是异步和增量方式进行的。此外,在传统分层架构中,多个应用程序共享同一个数据库是很常见的。所以,当数据库发生变化时,例如因应用程序更新或服务扩展而改变了数据布局,传统的应用程序都需要进行谨慎协调。反观事件驱动型应用,由于只需考虑自身数据,因此在更改数据表示或服务扩容时所需的协调工作将大大减少。

那么,Flink 如何支持事件驱动型应用程序呢?事件驱动型应用程序的能力取决于流处理引擎处理时间和状态的能力。Flink 提供了许多出色的功能来支持这些概念。它提供了一套丰富的状态操作原语,允许以精确一次的一致性语义合并海量规模(TB 级别)的状态数据。此外,Flink 支持事件时间处理、高度可定制的窗口逻辑以及 ProcessFunction 提供的对时间的细粒度控制,使得实现高级业务逻辑成为可能。另外,Flink 还提供了一个复杂事件处理(CEP)库。

不过,Flink 在支持事件驱动型应用程序方面的一个重要功能是保存点(savepoint)。保存点是一个一致性的状态快照,可以用来初始化任意状态兼容的应用。通过保存点,可以放心地对应用进行升级或扩容/缩容,还可以启动多个版本的应用程序来进行 A/B 测试。

典型的事件驱动型应用程序包括欺诈检测、异常检测、基于规则的警报、业务流程监控和网络应用(如社交网络)等。

数据分析应用

第二种应用类型是数据分析应用。数据分析应用是指从原始数据中提取信息和洞察力的分析工作。传统的分析方式是在记录事件的有界数据集上进行批量查询或构建应用程序的形式进行的。为了得到最新数据的分析结果,必须先将最新数据添加到原来的分析数据集中,并重新执行查询或运行应用程序。分析结果会写入存储系统或作为报告发布。

借助先进的流处理引擎,我们可以实时地进行数据分析。流式查询或应用程序不再读取有界的数据集,而是接收实时的事件流,并在处理事件时不断生成和更新结果。结果可能写入外部数据库,也可以保存为内部状态。仪表盘应用程序可以从外部数据库读取最新结果,或直接查询应用程序的内部状态。

Apache Flink 支持流式和批量数据分析应用,如下图所示。

image.png

与批量分析相比,流式分析应用有许多优势。首先,流式分析消除了周期性导入和查询执行所带来的延迟,能够实现更低的延迟。其次,与批量查询相比,流式查询不需要处理输入数据中的人为边界,这些边界是由周期性导入和有界输入造成的。

流式分析的另一个优势是简化的应用架构。批量分析管道通常包含多个独立组件,需要定期调度数据摄取和查询执行。可靠地运行此类管道并不容易,因为一旦出现故障,会影响后续步骤的执行。相比之下,在先进的流处理器(如 Flink)上运行的流式分析应用程序包含从数据摄取到连续结果计算的所有步骤。因此,它可以依赖底层引擎提供的故障恢复机制。

Flink 如何支持数据分析类应用?Flink 为持续流式分析和批量分析都提供了全面的支持。具体而言,它内置了一个符合 ANSI 标准的 SQL 接口,将批、流查询的语义统一起来。无论是在记录事件的静态数据集上还是实时事件流上,相同 SQL 查询都会得到一致的结果。同时,Flink 还支持丰富的用户自定义函数,允许在 SQL 中执行自定义代码。如果还需进一步自定义逻辑,Flink 的 DataStream API 和 DataSet API 可以提供更多底层控制。

典型的数据分析应用包括电信网络质量监控、移动应用中的产品更新分析及实验评估、消费者技术中的实时数据即时分析和大规模图分析等。

数据管道应用

第三种应用类型是数据管道应用。我们知道,提取-转换-加载(ETL,Extract-Transform-Load)是在存储系统之间进行数据转换和数据迁移的常用方法。ETL 作业通常会定期性地触发,将数据从事务型数据库系统拷贝到分析型数据库或数据仓库。

数据管道的作用与 ETL 作业类似。它们可以转换和丰富数据,并将数据从一个存储系统移动到另一个存储系统。不过,它们以持续流模式运行,而不是定期触发。因此,它们能够从持续产生数据的源中读取记录,并以较低的延迟将其移动到目的地。例如,数据管道可以监控文件系统目录中的新文件,并将其数据写入事件日志。另一个应用可能会将事件流物化到数据库中,或者增量构建和优化查询索引。

下图描述了定期 ETL 作业和持续数据管道之间的区别。

image.png

与周期性 ETL 作业相比,持续数据管道的明显优势在于减少了将数据传输到目的地的延迟。此外,数据管道的用途更广,支持的用例更多,因为它们能够持续消费和发送数据。

那 Flink 是如何支持数据管道应用呢?Flink 的 SQL 接口(或 Table API)及其对用户自定义函数的支持可以解决许多常见的数据转换或丰富任务。具有更高级要求的数据管道可通过使用更通用的 DataStream API 来实现。Flink 为 Kafka、Kinesis、Elasticsearch 和 JDBC 数据库系统等各种存储系统提供了丰富的连接器。同时,它还提供了文件系统的连续型数据源及数据汇,可用来监控目录变化和以时间分区的方式写入文件。

典型的数据管道应用包括电子商务中的实时搜索索引构建和电子商务中的持续 ETL。

小结

Flink 作为流行的开源流处理框架,支持三类常见的有状态的流处理应用,包括事件驱动型应用、数据管道应用和数据分析应用。通过使用 Flink,可以高效地处理有状态的数据流,实现各种复杂的实时数据处理任务。

(END)