Flink CDC系列之:Kafka Sink 的序列化器PipelineKafkaRecordSerializationSchema

这是一个 Flink CDC Kafka Sink 的序列化器,负责将 Change Data Capture (CDC) 事件序列化为 Kafka 消息。

核心功能

这个类实现了 KafkaRecordSerializationSchema,专门用于将 CDC 事件序列化为 Kafka 的 ProducerRecord。

关键组件
配置参数

  • partition: 分区策略(0分区或null)
  • keySerialization: Key 序列化器
  • valueSerialization: Value 序列化器
  • unifiedTopic: 统一主题名称
  • addTableToHeaderEnabled: 是否添加表信息到 Header
  • customHeaders: 自定义 Header 键值对
  • mappingRuleString: 表到主题的映射规则

构造函数逻辑

java 复制代码
PipelineKafkaRecordSerializationSchema(
    PartitionStrategy partitionStrategy,    // 分区策略
    SerializationSchema<Event> keySerialization,    // Key序列化
    SerializationSchema<Event> valueSerialization,  // Value序列化
    String unifiedTopic,                    // 统一主题
    boolean addTableToHeaderEnabled,        // 表头启用
    String customHeaderString,              // 自定义头字符串
    String mappingRuleString)               // 映射规则
  • 解析自定义 Header 字符串(格式:key1:value1;key2:value2)
  • 根据分区策略设置分区号

核心方法解析

serialize() - 序列化方法

java 复制代码
public ProducerRecord<byte[], byte[]> serialize(Event event, KafkaSinkContext context, Long timestamp) {
    // 1. 序列化 Key 和 Value
    ChangeEvent changeEvent = (ChangeEvent) event;
    final byte[] keySerialized = keySerialization.serialize(event);
    final byte[] valueSerialized = valueSerialization.serialize(event);
    
    // 2. 跳过 SchemaChangeEvent
    if (event instanceof SchemaChangeEvent) {
        return null;
    }
    
    // 3. 推断主题名称
    String topic = inferTopicName(changeEvent.tableId());
    
    // 4. 构建 Record Headers
    RecordHeaders recordHeaders = new RecordHeaders();
    
    // 添加表信息到 Header
    if (addTableToHeaderEnabled) {
        recordHeaders.add(new RecordHeader(NAMESPACE_HEADER_KEY, namespace.getBytes(UTF_8)));
        recordHeaders.add(new RecordHeader(SCHEMA_NAME_HEADER_KEY, schemaName.getBytes(UTF_8)));
        recordHeaders.add(new RecordHeader(TABLE_NAME_HEADER_KEY, tableName.getBytes(UTF_8)));
    }
    
    // 添加自定义 Header
    if (!this.customHeaders.isEmpty()) {
        for (Map.Entry<String, String> entry : customHeaders.entrySet()) {
            recordHeaders.add(new RecordHeader(entry.getKey(), entry.getValue().getBytes(UTF_8)));
        }
    }
    
    // 5. 创建 ProducerRecord
    return new ProducerRecord<>(
        topic, partition, null, keySerialized, valueSerialized, recordHeaders);
}

inferTopicName() - 主题推断逻辑

java 复制代码
private String inferTopicName(TableId tableId) {
    return tableIdToTopicCache.computeIfAbsent(tableId, (table -> {
        // 优先使用统一主题
        if (unifiedTopic != null && !unifiedTopic.isEmpty()) {
            return unifiedTopic;
        }
        // 其次使用映射规则匹配
        if (selectorsToTopicMap != null && !selectorsToTopicMap.isEmpty()) {
            for (Map.Entry<Selectors, String> entry : selectorsToTopicMap.entrySet()) {
                if (entry.getKey().isMatch(tableId)) {
                    return entry.getValue();
                }
            }
        }
        // 默认使用表名作为主题
        return table.toString();
    }));
}

open() - 初始化方法

java 复制代码
public void open(SerializationSchema.InitializationContext context, KafkaSinkContext sinkContext) {
    // 解析映射规则
    this.selectorsToTopicMap = KafkaSinkUtils.parseSelectorsToTopicMap(mappingRuleString);
    // 初始化缓存
    this.tableIdToTopicCache = new HashMap<>();
    // 初始化值序列化器
    valueSerialization.open(context);
}

重要特性

主题映射策略(优先级顺序)

  • 统一主题: 所有表数据发送到同一个主题
  • 规则映射: 根据表选择器规则映射到不同主题
  • 表名主题: 默认使用表名作为主题名

Header 信息丰富

  • 表结构信息: namespace, schemaName, tableName
  • 自定义 Header: 用户定义的任意键值对
  • 便于下游处理: 消费者可以根据 Header 识别数据来源

数据过滤

  • 跳过 SchemaChangeEvent: 只处理数据变更事件
  • 保留 ChangeEvent: 数据增删改事件

性能优化

  • 缓存机制: 表名到主题的映射缓存,避免重复计算

懒加载: 在 open 方法中初始化资源

应用场景

这个序列化器主要用于:

  • CDC 数据管道: 将数据库变更实时同步到 Kafka
  • 多租户架构: 不同表的数据路由到不同主题
  • 数据湖入湖: 为下游数据湖提供结构化的变更数据
  • 微服务数据同步: 各服务订阅相关表的变更数据
相关推荐
最笨的羊羊1 天前
Flink CDC系列之:Kafka 变更日志 JSON 格式工厂类 ChangeLogJsonFormatFactory
json·flink cdc系列·changelog·kafka 变更日志·json 格式工厂类·formatfactory
最笨的羊羊1 天前
Flink CDC系列之:Kafka Debezium JSON 序列化器的实现DebeziumJsonSerializationSchema
kafka·debezium·schema·flink cdc系列·serialization·序列化器·debezium json
最笨的羊羊2 天前
Flink CDC系列之:Kafka 数据接收器配置选项类KafkaDataSinkOptions
kafka·flink cdc系列·kafkadata·数据接收器配置选项类·sinkoptions
最笨的羊羊2 天前
Flink CDC系列之:Kafka JSON 序列化器JsonSerializationSchema
json·schema·flink cdc·serialization·序列化器·系列·kafkajson
最笨的羊羊2 天前
Flink CDC系列之: Kafka 数据接收器工厂类KafkaDataSinkFactory
kafka·flink cdc系列·数据接收器工厂类·kafkadata·sinkfactory
最笨的羊羊2 天前
Flink CDC系列之:Kafka 分区策略枚举类PartitionStrategy
partition·flink cdc系列·strategy·枚举类·kafka 分区策略
最笨的羊羊2 天前
Flink CDC系列之:Kafka表结构信息管理类TableSchemaInfo
flink cdc系列·kafka表结构信息·管理类·tableschemainfo
最笨的羊羊3 天前
Flink CDC系列之: Kafka 数据接收器实现类KafkaDataSink
kafka·flink cdc系列·数据接收器实现类·kafkadatasink
最笨的羊羊4 天前
Flink CDC系列之:Doris 模式工具类DorisSchemaUtils
doris·flink cdc系列·schemautils·模式工具类