输出算子
FileSink
- 在指定路径文件夹中,每一个并行子任务都会输出自己的文件
- 输出的文件可以通过OutputFileConfig来配置生成文件的前后缀
- 可以配置文件滚动策略
- 生成文件名中带有inprogress,说明这个文件是一个临时文件,还没有被commit,需要在检查点成功才会产生最终文件。所以需要设置checkpoint策略来确认写入
env.enableCheckpointing(2000, CheckpointingMode.EXACTLY_ONCE);
...数据读入、处理...
FileSink.DefaultRowFormatBuilder<Tuple2<String,Integer>> builder = FileSink.forRowFormat(new Path("outputs"), new SimpleStringEncoder<Tuple2<String,Integer>>())
.withOutputFileConfig(OutputFileConfig.builder().withPartPrefix("test01").withPartSuffix("log").build())
.withBucketAssigner(new DateTimeBucketAssigner<>("yyyy-mm-dd"))
.withRollingPolicy(DefaultRollingPolicy.builder()
.withRolloverInterval(Duration.ofSeconds(10))
.withMaxPartSize(new MemorySize(1024 * 1024)).build());
FileSink<Tuple2<String,Integer>> fileSink = builder.build();
res.sinkTo(fileSink);
KafkaSink
- 使用setBootstrapServers配置要连接的kafka集群
- 使用setValueSerializationSchema进行更详细的序列化配置
- 当DeliveryGuarantee配置为EXACTLY_ONCE时必须设置事务的前缀和checkpoint
KafkaSink<Tuple2<String, Integer>> kafkaSink = KafkaSink.<Tuple2<String, Integer>>builder().setBootstrapServers("addr:9192")
.setRecordSerializer(KafkaRecordSerializationSchema.builder()
.setTopic("quickstart-events")
.setValueSerializationSchema(new SerializationSchema<Tuple2<String, Integer>>() {
@Override
public byte[] serialize(Tuple2<String, Integer> stringIntegerTuple2) {
StringBuilder builder = new StringBuilder();
builder.append("(" + stringIntegerTuple2.f0 + "," + stringIntegerTuple2.f1 + ")");
return builder.toString().getBytes(StandardCharsets.UTF_8);
}
}).build())
.setDeliveryGuarantee(DeliveryGuarantee.AT_LEAST_ONCE)
.build();
res.sinkTo(kafkaSink);
JdbcSink
- flink的1.18版本中,jdbc的输出算子仍使用旧版的addsink写法
- 数据库连接信息在JdbcConnectionOptions中配置
- 如果想立刻看到数据库更新,需要配置JdbcExecutionOptions(批量写入、重试配置)
ds.addSink(JdbcSink.sink("insert into test01.watersensor (id, ts, vc) VALUES (?,?,?)", (JdbcStatementBuilder<String>) (preparedStatement, s) -> {
String[] strings = s.split(" ");
preparedStatement.setObject(1,strings[0]);
preparedStatement.setObject(2,Long.valueOf(strings[1]));
preparedStatement.setObject(3,Integer.valueOf(strings[2]));
System.out.println(preparedStatement);
}, JdbcExecutionOptions.builder()
.withBatchSize(1)
.withBatchIntervalMs(0)
.withMaxRetries(3)
.build(),
new JdbcConnectionOptions.JdbcConnectionOptionsBuilder().withUrl("jdbc:mysql://addr:3306")
.withDriverName("com.mysql.cj.jdbc.Driver")
.withUsername("root")
.withPassword("123456").build()));