Flink是第三代分布式流处理器,它的功能丰富且强大。
Flink区别于传统数据处理框架的特性如下。
· 高吞吐和低延迟。Flink每秒处理数百万个事件;具有毫秒级延迟。
· 结果的准确性。Flink提供了事件时间(event-time)和处理时间(processing-time)语义。对于乱序事件流,事件时间语义仍然能提供一致且准确的结果。
· exactly-once(精确一次)的状态一致性保证。
· Flink可以连接到最常用的存储系统,如Apache Kafka、Apache Cassandra、ElasticSearch、JDBC、Kinesis,以及分布式文件系统如HDFS和S3。
· 高可用。Flink本身高可用的设置,加上与K8s(Kubernetes)、YARN和Mesos的紧密集成,再加上从故障中快速恢复和动态扩展任务的能力,能做到以极短的停机时间实现7×24小时全天候运行。
· Flink能够更新应用程序代码并将作业(jobs)迁移到不同的Flink集群中而不会丢失应用程序的状态。
除了上述这些特性,Flink还是一个非常易于开发的框架,因为它拥有易于使用的分层API,如图1-11所示。
图1-11 Flink不同级别的API
最底层的API仅仅提供了有状态流,将处理函数(Process Function)嵌入DataStream API中。底层处理函数与DataStream API集成,可以对某些操作进行抽象,允许用户使用自定义状态处理来自一个或多个数据流的事件,且状态具有一致性和容错保证。此外,用户还可以注册事件时间并处理时间回调,从而使程序可以处理复杂的计算。
实际上,大多数应用并不需要上述的底层抽象,而直接针对核心API(Core API)进行编程,如DataStream API(用于处理有界或无界流数据)及DataSet API(用于处理有界数据集)。这些API为数据处理提供了通用的构建模块,如由用户自定义的多种形式的转换(transformation)、联结(join)、聚合(aggregation)、窗口(window)操作等。DataSet API为有界数据集提供了额外的支持,如循环与迭代。这些API处理的数据类型以类(class)的形式由各自的编程语言表示。
Table API是以表为中心的声明式编程,其中的表在表达流数据时会动态变化。Table API遵循关系模型:表有二维数据结构(schema)(类似于关系数据库中的表),同时API提供可比较的操作,如select、join、group-by、aggregate等。
尽管Table API可以通过多种类型的用户自定义函数(UDF)进行扩展,但仍不如核心API具有表达能力(但是Table API的代码量更少、更加简洁)。此外,Table API程序在执行之前会使用内置优化器进行优化。
我们可以在表与DataStream/DataSet之间无缝切换,以允许程序将Table API与DataStream/DataSet混合使用。
Flink提供的最高层级的API是SQL。这一层API在语法和表达能力上与Table API类似,但是是以SQL查询表达式的形式表现程序的。SQL API与Table API交互密切,同时,SQL查询可以直接在Table API定义的表上执行。
目前,Flink SQL和Table API还在开发完善的过程中,很多大型企业都会二次开发符合自己需要的工具包,而DataSet作为批处理API,实际应用较少,2020年12月8日发布的新版本Flink 1.12.0已经完全实现了真正的流批一体,DataSet API已处于软性弃用(soft deprecated)状态。用Data Stream API写好的一套代码既可以处理流数据,又可以处理批数据,只需设置不同的执行模式即可。这与之前版本处理有界流的方式是不一样的,Flink已专门对批处理数据做了优化处理。本书以介绍DataStream API为主,采用的版本是Flink 1.13.0。