文章目录
1. 背景
现有自定义redis sink的需求,我们借此学习一下如何自定义flink sink connector,以及flink是如何通过ddl建表语句中的properties来定位具体的TableFactory,进而创建StreamTableSink的。
该文介绍的写法是Flink1.10之前的写法,Flink1.11之后的版本在兼容该文所介绍的写法的同时,对用户自定义Source和Sink相关逻辑进行了重构,详情请参考官方文档。
2. user-defined redis sink
文中代码详情请参考github。
如果只是利用DataStream API定义一个sink connector,则实现SinkFunction接口,然后调用datastream.addSink(redisSink)即可,详情参考源码中的RedisSinkITCase#testRedisListDataType测试用例。
如果想要在Table API / SQL DDL中使用自定义sink connector,则需要依次实现
TableSinkFactory -> TableSink -> SinkFunction。
2.1 RedisTableSinkFactory
Flink使用SPI查找到ClassPath下所有的TableSinkFactory class对象(下节详细介绍),并通过DDL中定义的properties来查找需要实例化的具体TableSinkFactory。
/**
* redis table sink factory for creare redis table sink.
*/
public class RedisTableSinkFactory implements StreamTableSinkFactory<Tuple2<Boolean, Row>> {
// 将DDL中的属性解析成入参properties,并创建TableSink
@Override
public StreamTableSink<Tuple2<Boolean, Row>> createStreamTableSink(Map<String, String> properties) {
return new RedisTableSink(properties);
}
// 根据这里定义的属性,从众多TableSinkFactory实例中精确定位需要使用的TableSinkFactory
@Override
public Map<String, String> requiredContext() {
Map<String, String> require = new HashMap<>();
require.put(CONNECTOR_TYPE, REDIS);
return require;
}
// 预先定义可以写在DDL中的properties,如果在TableSinkFactory查找过程中,发现DDL中properties全部属于在此定义的properties,则认为该TableFactory即为要使用的TableFactory
// 可以认为,supportedProperties()方法中的properties和requiredContext()方法中的properties都是用来精确定位TableSinkFactory实现类的
@Override
public List<String> supportedProperties() {
List<String> properties = new ArrayList<>();
properties.add(REDIS_MODE);
properties.add(REDIS_COMMAND);
properties.add(REDIS_NODES);
properties.add(REDIS_MASTER_NAME);
properties.add(REDIS_SENTINEL);
properties.add(REDIS_KEY_TTL);
// schema
properties.add(SCHEMA + ".#." + SCHEMA_DATA_TYPE);
properties.add(SCHEMA + ".#." + SCHEMA_NAME);
// format wildcard
properties.add(CONNECTOR + ".*");
// standalone
properties.add(REDIS_SERVER_IP);
properties.add(REDIS_SERVER_PORT);
return properties;
}
}
2.2 RedisTableSink
通过SPI定位到具体TableFactory之后,会创建TableSink并消费上游的流数据。
public class RedisTableSink implements UpsertStreamTableSink<Row> {
...
// 创建SinkFunction
@Override
public DataS

最低0.47元/天 解锁文章
611

被折叠的 条评论
为什么被折叠?



