Flink 的 sink 实战之一:初探
从一段实例代码开始
下面是个简单的 flink 应用代码,红框中的 print 方法就是 sink 操作:

下图是官方给出的 sink 方式,都是 DataStream 类的 API,直接调用即可实现 sink,刚才代码中的 print 就是其中一个:

接下来看看上图中 API 的源码,先看 print 方法,在 DataStream.java 中,如下,实际上是调用了 addSink 方法,入参是 PrintSinkFunction:

另一个常用 API 是 writeAsText,源码如下,调用了 writeUsingOutputFormat 方法:

追踪 writeUsingOutputFormat 发现也是调用了 addSink,入参是 OutputFormatSinkFunction:

print 和 writeAsText 背后都在调用 addSink,那么另一个常用的 writeAsCsv 方法呢?莫非也是调用 addSink?打开一看果然,和 writeAsText 一样调用了 writeUsingOutputFormat,而该方法里面就是在调用 addSink:

综上所述,data sink 的关键就是 addSink 的入参,即 SinkFunction 接口的实现,通过类图直观看到常见的 sink 能力是如何实现的:

从上图可见抽象类 RichSinkFunction 与各种 sink 能力的关系十分紧密,我们应该重点关注它,在类图上展示方法签名,如下图:

如上图所示,RichSinkFunction 本身没有内容,但是它实现 SinkFunction,继承 AbstractRichFunction,是 RichFunction 和 SinkFunction 这两种特性的结合;
RichFunction 的特性在前面的《Flink的DataSource三部曲》中已经了解,就是资源的 open 和 close;
SinkFunction 的特性呢?显然是用来处理计算结果的,类图上显示的是两个 invoke 方法,来看看官方的 PrintSinkFunction.java:

writer.write(record)的源码在 PrintSinkOutputWriter.java,如下所示:

小结
至此,我们已经对 Flink 的 sink 有了基本了解:
负责实时计算结果的处理(如输出或持久化);
主要实现方式是调用 DataStream.addSink 方法;
各种 sink 能力的实现,主要途径是实现 addSink 方法的入参定义的接口;
评论