Flink CDC系列之:Kafka的Debezium JSON 结构定义类DebeziumJsonStruct

这是一个 Debezium JSON 结构定义类,使用枚举来定义 Debezium JSON 格式的字段结构和位置信息。

类概述

java 复制代码
public class DebeziumJsonStruct

这个类通过嵌套枚举定义了 Debezium JSON 格式的完整结构,包括字段名称和位置信息。

嵌套枚举详解
DebeziumStruct - 顶层结构

java 复制代码
enum DebeziumStruct {
    SCHEMA(0, "schema"),
    PAYLOAD(1, "payload");

作用:定义 Debezium JSON 的顶层结构字段。

字段说明:

  • SCHEMA(0, "schema"):表结构信息(位置0,字段名"schema")
  • PAYLOAD(1, "payload"):数据负载信息(位置1,字段名"payload")

对应的 JSON 结构:

java 复制代码
{
  "schema": { ... },    // SCHEMA 字段
  "payload": { ... }    // PAYLOAD 字段
}

DebeziumPayload - 数据负载结构

java 复制代码
enum DebeziumPayload {
    BEFORE(0, "before"),
    AFTER(1, "after"),
    OPERATION(2, "op"),
    SOURCE(3, "source");

作用:定义 payload 对象内部的字段结构。

字段说明:

  • BEFORE(0, "before"):变更前的数据(位置0,字段名"before")
  • AFTER(1, "after"):变更后的数据(位置1,字段名"after")
  • OPERATION(2, "op"):操作类型(位置2,字段名"op")
  • SOURCE(3, "source"):源数据库信息(位置3,字段名"source")

对应的 JSON 结构:

java 复制代码
{
  "payload": {
    "before": { ... },      // BEFORE 字段
    "after": { ... },       // AFTER 字段  
    "op": "c",             // OPERATION 字段
    "source": { ... }      // SOURCE 字段
  }
}

DebeziumSource - 源信息结构

java 复制代码
enum DebeziumSource {
    DATABASE(0, "db"),
    TABLE(1, "table");

作用:定义 source 对象内部的字段结构。

字段说明:

  • DATABASE(0, "db"):数据库名称(位置0,字段名"db")
  • TABLE(1, "table"):表名称(位置1,字段名"table")

对应的 JSON 结构:

java 复制代码
{
  "source": {
    "db": "inventory",     // DATABASE 字段
    "table": "users"       // TABLE 字段
  }
}

枚举设计特点

位置和名称双重映射

java 复制代码
private final int position;    // 位置索引
private final String fieldName; // 字段名称

优势:

  • 可以通过位置快速访问
  • 可以通过名称清晰标识

类型安全

使用枚举替代字符串常量,避免拼写错误:

java 复制代码
// 安全的方式
DebeziumPayload.BEFORE.getFieldName()  // 返回 "before"

// 不安全的方式(容易拼错)
String field = "befor";  // 拼写错误

易于扩展

添加新字段只需在对应枚举中添加新值:

java 复制代码
enum DebeziumPayload {
    // 现有字段...
    TIMESTAMP(4, "ts_ms"),      // 新增时间戳字段
    TRANSACTION(5, "transaction"); // 新增事务字段

实际使用场景

在序列化器中的使用

java 复制代码
public class DebeziumJsonSerializationSchema {
    
    public byte[] serialize(Event event) {
        // 构建 Debezium JSON 结构
        ObjectNode rootNode = objectMapper.createObjectNode();
        
        // 使用枚举确保字段名称一致
        rootNode.set(
            DebeziumStruct.SCHEMA.getFieldName(), 
            buildSchemaNode()
        );
        
        rootNode.set(
            DebeziumStruct.PAYLOAD.getFieldName(),
            buildPayloadNode(event)
        );
        
        return objectMapper.writeValueAsBytes(rootNode);
    }
    
    private ObjectNode buildPayloadNode(Event event) {
        ObjectNode payloadNode = objectMapper.createObjectNode();
        
        // 设置操作类型
        payloadNode.put(
            DebeziumPayload.OPERATION.getFieldName(),
            getOperationCode(event.op())
        );
        
        // 设置前后数据
        payloadNode.set(
            DebeziumPayload.BEFORE.getFieldName(),
            convertToJson(event.before())
        );
        
        payloadNode.set(
            DebeziumPayload.AFTER.getFieldName(), 
            convertToJson(event.after())
        );
        
        // 设置源信息
        payloadNode.set(
            DebeziumPayload.SOURCE.getFieldName(),
            buildSourceNode(event.tableId())
        );
        
        return payloadNode;
    }
    
    private ObjectNode buildSourceNode(TableId tableId) {
        ObjectNode sourceNode = objectMapper.createObjectNode();
        
        sourceNode.put(
            DebeziumSource.DATABASE.getFieldName(),
            tableId.getSchemaName()
        );
        
        sourceNode.put(
            DebeziumSource.TABLE.getFieldName(),
            tableId.getTableName()
        );
        
        return sourceNode;
    }
}

在反序列化器中的使用

java 复制代码
public class DebeziumJsonDeserializationSchema {
    
    public Event deserialize(byte[] message) {
        JsonNode rootNode = objectMapper.readTree(message);
        
        // 使用枚举字段名获取节点
        JsonNode payloadNode = rootNode.get(
            DebeziumStruct.PAYLOAD.getFieldName()
        );
        
        // 解析操作类型
        String operation = payloadNode.get(
            DebeziumPayload.OPERATION.getFieldName()
        ).asText();
        
        // 解析源信息
        JsonNode sourceNode = payloadNode.get(
            DebeziumPayload.SOURCE.getFieldName()
        );
        
        String database = sourceNode.get(
            DebeziumSource.DATABASE.getFieldName()
        ).asText();
        
        String table = sourceNode.get(
            DebeziumSource.TABLE.getFieldName()
        ).asText();
        
        // ... 其他解析逻辑
    }
}

生成的完整 JSON 示例

基于这个结构定义,会生成如下格式的 JSON:

java 复制代码
{
  "schema": {
    "type": "struct",
    "fields": [
      {
        "type": "struct",
        "fields": [
          {"type": "int32", "optional": false, "field": "id"},
          {"type": "string", "optional": true, "field": "name"}
        ],
        "optional": true,
        "name": "mysql-server-1.inventory.users.Value",
        "field": "before"
      }
    ],
    "optional": false,
    "name": "mysql-server-1.inventory.users.Envelope"
  },
  "payload": {
    "before": null,
    "after": {
      "id": 1001,
      "name": "张三"
    },
    "op": "c",
    "source": {
      "db": "inventory",
      "table": "users"
    }
  }
}

扩展建议

当前定义比较基础,实际 Debezium 格式包含更多字段,可以扩展为:

java 复制代码
enum DebeziumPayload {
    BEFORE(0, "before"),
    AFTER(1, "after"), 
    OPERATION(2, "op"),
    SOURCE(3, "source"),
    TIMESTAMP(4, "ts_ms"),
    TRANSACTION(5, "transaction");
}

enum DebeziumSource {
    DATABASE(0, "db"),
    TABLE(1, "table"),
    SERVER_ID(2, "server_id"),
    BINLOG_FILE(3, "file"),
    BINLOG_POSITION(4, "pos"),
    CONNECTOR(5, "connector"),
    SNAPSHOT(6, "snapshot");
}

总结:DebeziumJsonStruct 是一个结构定义类,它通过嵌套枚举:

✅ 定义标准结构:完整定义 Debezium JSON 格式的字段结构

✅ 提供类型安全:使用枚举替代字符串常量,避免拼写错误

✅ 支持双向访问:既可以通过名称访问,也可以通过位置访问

✅ 易于维护扩展:集中管理字段定义,支持轻松添加新字段

✅ 提高代码可读性:清晰的枚举名称使代码意图更明确

这个类是 Debezium JSON 序列化和反序列化组件的基础,确保了数据格式的规范性和一致性。

相关推荐
原神启动13 小时前
Kafka详解
分布式·kafka
一只懒鱼a7 小时前
搭建kafka集群(安装包 + docker方式)
运维·容器·kafka
青春不流名8 小时前
如何在Kafka中使用SSL/TLS证书认证
分布式·kafka·ssl
青春不流名8 小时前
Kafka 的认证机制
kafka
hanyi_qwe8 小时前
ZooKeeper+Kafka
分布式·zookeeper·kafka
BullSmall10 小时前
Kafka 安全加固实践指南(可直接落地)
分布式·安全·kafka
Chasing__Dreams13 小时前
kafka--基础知识点--6.4--LSO
数据库·分布式·kafka
Query*20 小时前
分布式消息队列kafka【五】—— kafka海量日志收集实战
分布式·kafka
lang201509281 天前
Kafka元数据缓存机制深度解析
分布式·缓存·kafka
qq_343247031 天前
单机版认证kafka
数据库·分布式·kafka