一、共同点
- 都是继承自 org.apache.flink.streaming.api.functions.sink.RichSinkFunction
- 都可以将分区文件,以桶的形式写入文件系统
- 都可以设置桶的命名、滚动策略、写入方式、检查间隔等
- 默认的桶名称,都是以系统时间yyyy-MM-dd--HH
- 文件有三种状态:in-progress,pending 和 finished。
二、不同点
1、StreamFileSink
- 输出使用的是OutputStream,以字节流的形式输出,直接对byte[]进行操作,不会更改任何信息,真实的反映数据内容。
- 间隔检查时间, 是以系统时间0秒时刻开始算的。如10:00:10运行程序,inactivityInterval=300s,bucketCheckInterval=60s,最后一次写入时间是10:05:30。则在10:11:00时,将in-process文件转为正式文件。
- 默认的文件大小是128M,默认的滚动写入新文件的时间是60s。
2、BucketingSink
- 输出使用的是Writer,以字符流的形式输出,需要使用缓冲区。
- 间隔检查时间, 是以运行时间开始算的。如10:00:10运行程序,inactiveBucketThreshold=300s,inactiveBucketCheckInterval=60s,最后一次写入时间是10:05:30。则在10:11:10时,将in-process文件转为正式文件。
- 可以设置文件的前缀和后缀。
- 默认的文件大小是384M,默认的滚动写入新文件的时间是 Long.MAX_VALUE。
- 需要启用checkpoint,否则数据会一直在缓冲区中。直到到达滚动阀值时,才会把数据写到文件中,文件状态由in-process,转为pending,不会转为finished。
三、问答
Q1:三种文件状态是如何转换的?
A:当记录来的时候,会根据Bucket目录路径设置,创建一个文件,文件会以下划线"_"开头,in-process结尾。此时,数据还在内存中,不会刷到文件系统。当checkpoint的时候,会将内存的数据刷到文件系统。当文件需要进行翻滚,但是还未到达checkpoint时,会将该目录下的in-process文件rename成以下划线"_"开头,in-appending结尾的文件。当收到checkpoint完成时的事件,会将该目录下in-appending文件最终转化成finished文件。
Q2:数据何时刷到文件系统?
A:当checkpoint完成的时候,会将内存数据落到文件系统。
Q3:出现异常时,Kafka如何容错?
A:出现异常时,当前内存中的数据将会丢失。Kafka Source的offset将会重置到上一个checkpoint的offset重新消费,并且创建新文件。