Flink CDC系列之:数据接收器工厂类DorisDataSinkFactory
java
public class DorisDataSinkFactory implements DataSinkFactory
这是一个实现了 DataSinkFactory 接口的工厂类,专门用于创建 Doris 数据库的数据接收器。
createDataSink(Context context) - 创建数据接收器
这是工厂类的核心方法,负责构建 Doris 数据接收器:
java
@Override
public DataSink createDataSink(Context context) {
// 1. 配置验证
FactoryHelper.createFactoryHelper(this, context)
.validateExcept(
TABLE_CREATE_PROPERTIES_PREFIX,
STREAM_LOAD_PROP_PREFIX,
TABLE_CREATE_AUTO_PARTITION_PROPERTIES_PREFIX);
配置验证:使用 FactoryHelper 验证配置,但排除某些前缀的配置项(这些是 Doris 特定的配置)。
Doris 连接配置
java
Configuration config = context.getFactoryConfiguration();
DorisOptions.Builder optionsBuilder = DorisOptions.builder();
// 设置 Doris 连接参数
config.getOptional(FENODES).ifPresent(optionsBuilder::setFenodes); // FE 节点地址
config.getOptional(BENODES).ifPresent(optionsBuilder::setBenodes); // BE 节点地址
config.getOptional(USERNAME).ifPresent(optionsBuilder::setUsername); // 用户名
config.getOptional(PASSWORD).ifPresent(optionsBuilder::setPassword); // 密码
config.getOptional(JDBC_URL).ifPresent(optionsBuilder::setJdbcUrl); // JDBC URL
config.getOptional(AUTO_REDIRECT).ifPresent(optionsBuilder::setAutoRedirect); // 自动重定向
DorisOptions:配置 Doris 数据库的连接信息。
这段代码涉及到了 Apache Flink 和 Doris 的配置。让我们逐步解析:
- Configuration config = context.getFactoryConfiguration();
- 这行代码从 context 对象中获取了一个 Configuration 对象。
- context 通常是一个上下文对象,可能包含了应用的各种配置信息。
- LisgetFactoryConfiguration() 方法返回一个 Configuration 对象,该对象包含了工厂级别的配置信息。
- DorisOptions.Builder optionsBuilder = DorisOptions.builder();
- 这行代码创建了一个 DorisOptions.Builder 对象。DorisOptions 是一个用于配置 Doris 连接的选项类,Builder 模式允许你逐步构建这些选项。
- DorisOptions.builder() 是一个静态方法,返回一个 DorisOptions.Builder 实例。
- config.getOptional(FENODES).ifPresent(optionsBuilder::setFenodes);
- 这行代码从 config 对象中获取一个可选的配置项 FENODES。
getOptional(FENODES) 方法返回一个 Optional 对象,表示 FENODES 配置项可能存在也可能不存在。 - ifPresent(optionsBuilder::setFenodes) 方法检查 Optional 对象是否有值,如果有值,则调用 optionsBuilder.setFenodes 方法将该值设置到 DorisOptions 中。
执行参数配置
java
DorisExecutionOptions.Builder executionBuilder = DorisExecutionOptions.builder();
// 设置执行参数
config.getOptional(SINK_CHECK_INTERVAL).ifPresent(executionBuilder::setCheckInterval);
config.getOptional(SINK_MAX_RETRIES).ifPresent(executionBuilder::setMaxRetries);
config.getOptional(SINK_ENABLE_DELETE).ifPresent(executionBuilder::setDeletable);
config.getOptional(SINK_LABEL_PREFIX).ifPresent(executionBuilder::setLabelPrefix);
config.getOptional(SINK_BUFFER_SIZE).ifPresent(executionBuilder::setBufferSize);
config.getOptional(SINK_BUFFER_COUNT).ifPresent(executionBuilder::setBufferCount);
关键参数说明:
- SINK_CHECK_INTERVAL:检查间隔
- SINK_MAX_RETRIES:最大重试次数
- SINK_LABEL_PREFIX:导入任务标签前缀
- SINK_BUFFER_SIZE:缓冲区大小
- SINK_BUFFER_COUNT:缓冲区数量
批量处理配置
java
config.getOptional(SINK_BUFFER_FLUSH_MAX_ROWS)
.ifPresent(executionBuilder::setBufferFlushMaxRows); // 最大刷出行数
config.getOptional(SINK_BUFFER_FLUSH_MAX_BYTES)
.ifPresent(executionBuilder::setBufferFlushMaxBytes); // 最大刷出字节数
config.getOptional(SINK_FLUSH_QUEUE_SIZE).ifPresent(executionBuilder::setFlushQueueSize); // 刷新队列大小
config.getOptional(SINK_IGNORE_UPDATE_BEFORE)
.ifPresent(executionBuilder::setIgnoreUpdateBefore); // 忽略 UPDATE_BEFORE
config.getOptional(SINK_USE_CACHE).ifPresent(executionBuilder::setUseCache); // 使用缓存
// 设置刷新间隔
config.getOptional(SINK_BUFFER_FLUSH_INTERVAL)
.ifPresent(v -> executionBuilder.setBufferFlushIntervalMs(v.toMillis()));
两阶段提交配置
java
config.getOptional(SINK_ENABLE_2PC)
.ifPresent(
b -> {
if (b) {
executionBuilder.enable2PC(); // 启用两阶段提交
} else {
executionBuilder.disable2PC(); // 禁用两阶段提交
}
});
两阶段提交:提供精确一次语义(exactly-once)的数据一致性保证。
批量模式配置
java
// default batch mode
executionBuilder.setBatchMode(config.get(SINK_ENABLE_BATCH_MODE));
批量模式:控制是否启用批量写入。
Stream Load 属性配置
java
// set streamload properties
Properties properties = DorisExecutionOptions.defaultsProperties();
Map<String, String> streamLoadProp =
DorisDataSinkOptions.getPropertiesByPrefix(config, STREAM_LOAD_PROP_PREFIX);
properties.putAll(streamLoadProp);
executionBuilder.setStreamLoadProp(properties);
Stream Load:Doris 的数据导入方式,这里配置相关的属性。
这段代码主要用于配置 Doris 的 Stream Load 属性。让我们逐行解释:
java
Properties properties = DorisExecutionOptions.defaultsProperties();
这行代码创建了一个 Properties 对象,并初始化为 Doris 执行选项的默认属性。DorisExecutionOptions.defaultsProperties() 方法返回一个包含默认 Stream Load 属性的 Properties 对象。
java
Map<String, String> streamLoadProp =
DorisDataSinkOptions.getPropertiesByPrefix(config, STREAM_LOAD_PROP_PREFIX);
这行代码从 config 中提取所有以 STREAM_LOAD_PROP_PREFIX 为前缀的属性,并将它们存储在一个 Map<String, String> 对象中。DorisDataSinkOptions.getPropertiesByPrefix(config, STREAM_LOAD_PROP_PREFIX) 方法用于过滤并提取这些属性。
java
properties.putAll(streamLoadProp);
这行代码将从 config 中提取的 Stream Load 属性添加到 properties 对象中。putAll 方法会将 streamLoadProp 中的所有键值对添加到 properties 中,覆盖已存在的同名属性。
java
executionBuilder.setStreamLoadProp(properties);
最后,这行代码将配置好的 properties 对象设置到 executionBuilder 中。executionBuilder 是一个构建器对象,用于构建 Doris 的执行配置。setStreamLoadProp 方法将 properties 中的属性应用到 Stream Load 配置中。
创建 DorisDataSink 实例
java
return new DorisDataSink(
optionsBuilder.build(), // Doris 连接选项
DorisReadOptions.builder().build(), // Doris 读取选项(使用默认值)
executionBuilder.build(), // 执行选项
config, // 原始配置
ZoneId.of( // 时区配置
context.getPipelineConfiguration()
.get(PipelineOptions.PIPELINE_LOCAL_TIME_ZONE)));
工厂标识方法
java
@Override
public String identifier() {
return "doris";
}
标识符:在 Flink SQL 中使用的连接器名称,如 CREATE TABLE ... WITH ('connector' = 'doris')。
必需和可选配置项
必需配置项
java
@Override
public Set<ConfigOption<?>> requiredOptions() {
Set<ConfigOption<?>> options = new HashSet<>();
options.add(FENODES); // FE 节点地址(必须)
options.add(USERNAME); // 用户名(必须)
return options;
}
可选配置项
java
@Override
public Set<ConfigOption<?>> optionalOptions() {
Set<ConfigOption<?>> options = new HashSet<>();
// 连接配置
options.add(BENODES);
options.add(JDBC_URL);
options.add(PASSWORD);
options.add(AUTO_REDIRECT);
// 执行配置
options.add(SINK_CHECK_INTERVAL);
options.add(SINK_ENABLE_2PC);
options.add(SINK_MAX_RETRIES);
options.add(SINK_ENABLE_DELETE);
options.add(SINK_LABEL_PREFIX);
// 批量处理配置
options.add(SINK_BUFFER_SIZE);
options.add(SINK_BUFFER_COUNT);
options.add(SINK_ENABLE_BATCH_MODE);
options.add(SINK_BUFFER_FLUSH_MAX_ROWS);
options.add(SINK_BUFFER_FLUSH_MAX_BYTES);
options.add(SINK_BUFFER_FLUSH_INTERVAL);
return options;
}
在 Flink CDC 中使用
java
// 在 Flink CDC Pipeline 配置中
mysql-sync-database
--database source_db
--sink-conf connector=doris
--sink-conf fenodes=fe1:8030,fe2:8030
--sink-conf username=user
--sink-conf password=pass
--sink-conf database-name=target_db
--sink-conf sink.label-prefix=cdc
--sink-conf sink.max-retries=5