2.1 API层级
对Flink业务代码开发人员来说,非常重要的是了解如何使用Flink编程模型中的API。Flink将API抽象成了图2-1所示的层级结构。
图2-1 Flink中的API层级结构
在图2-1所示的层级结构中,上层并不是下层的高级封装,该结构展示抽象程度和易用性程度。
底层的状态流处理API的抽象程度最低,而且它只能用于流处理。不过它提供了非常灵活的接口,可以用于自定义底层与状态、时间相关的操作。
DataStream/DataSet API这一层级的API是Flink中的核心API。这一层级中要处理的数据会被抽象成数据流(DataStream)或数据集(DataSet),然后在其上通过定义转换操作实现业务逻辑。这一层级的API的使用风格与Java 8中的Stream编程风格十分类似。
在DataStream/DataSet API之上是Table API。Table API和DataStream/DataSet API不同,不是用复杂的函数定义业务过程的,而是用陈述性的语言加以描述。这样就可大大地降低编程难度,增强描述性。这种语言来自SQL语法,只不过以API的形式呈现出来。既然有了Table API,那么自然可以直接使用SQL来进行描述。这就是最上层的SQL。
总而言之,越上层的API,其描述性和可读性越强;越下层的API,其灵活度越高、表达力越强。多数时候上层API能做到的事,下层API也能做到,反过来却未必。不过,这些API的底层模型是一致的,可以混合使用。
敏锐的读者或许可以从中得到一个推论:当我们用上层API开发业务代码时,在Flink内部会有一个将其转化为底层API的“翻译”过程(比如用SQL开发时,会有各种规则对执行计划进行优化),而这个过程不是业务开发人员可以介入的,得到的结果很有可能不是最优的。这就好比我们用高级语言进行开发,虽然开发效率得到了提高,但是系统的性能往往不如使用底层语言进行开发时那么高。这也提示了我们学习底层实现原理的必要性——从理论上来讲,要想写出性能最佳的Flink业务代码,就应该在理解其转换规则和运行的原理后,用底层的API进行开发。若有余力,则可以思考如何优化转换规则,使框架能够自动生成最佳执行计划。
一般来说,DataStream/DataSet API及其上层API已经能够描述清楚整个业务场景,需要用到底层API的场景较少,因此下面会略过底层的API,直接从核心API层开始介绍。