Flink CDC 用 Db2 CDC 实时同步数据到 Elasticsearch

一、整体环境概览

我们用一份 docker-compose.yml 一次性起三套服务:

  • Db2 :带预置测试库 TESTDB,里面有 DB2INST1.PRODUCTS 表;
  • Elasticsearch 7.6.0:作为 Flink 的下游 sink;
  • Kibana 7.6.0:方便在浏览器里查看 Elasticsearch 的数据。

docker-compose.yml 如下:

yaml 复制代码
version: '2.1'
services:
  db2:
    image: ruanhang/db2-cdc-demo:v1
    privileged: true
    ports:
      - 50000:50000
    environment: 
      - LICENSE=accept
      - DB2INSTANCE=db2inst1
      - DB2INST1_PASSWORD=admin
      - DBNAME=testdb    
      - ARCHIVE_LOGS=true

  elasticsearch:
    image: elastic/elasticsearch:7.6.0
    environment:
      - cluster.name=docker-cluster
      - bootstrap.memory_lock=true
      - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
      - discovery.type=single-node
    ports:
      - "9200:9200"
      - "9300:9300"
    ulimits:
      memlock:
        soft: -1
        hard: -1
      nofile:
        soft: 65536
        hard: 65536

  kibana:
    image: elastic/kibana:7.6.0
    ports:
      - "5601:5601"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock

启动环境:

bash 复制代码
docker-compose up -d
docker ps

浏览器打开:http://localhost:5601/,看到 Kibana 正常起来就说明 ES 也 OK 了。

结束实验记得:

bash 复制代码
docker-compose down

Flink 这边,需要把 Db2 CDC 和 ES7 连接器的 JAR 丢到 <FLINK_HOME>/lib 下:

  • flink-sql-connector-elasticsearch7-3.0.1-1.17.jar
  • flink-sql-connector-db2-cdc-3.0-SNAPSHOT.jar

注意:3.0-SNAPSHOT 一般需要自己从 master / release 分支编译,稳定版本才有直接的下载链接。

然后启动一个 Flink 集群(Standalone / Yarn / K8s 都可以),再打开 Flink SQL CLI。

在 Flink SQL CLI 中先开启 checkpoint(保证容错与状态一致性):

sql 复制代码
-- 每 3 秒做一次 checkpoint
SET execution.checkpointing.interval = 3s;

1. 定义 Db2 CDC 源表

products 表对应 Db2 里的 DB2INST1.PRODUCTS

sql 复制代码
CREATE TABLE products (
    ID INT NOT NULL,
    NAME STRING,
    DESCRIPTION STRING,
    WEIGHT DECIMAL(10,3),
    PRIMARY KEY (ID) NOT ENFORCED
) WITH (
    'connector' = 'db2-cdc',
    'hostname' = 'localhost',
    'port' = '50000',
    'username' = 'db2inst1',
    'password' = 'admin',
    'database-name' = 'TESTDB',
    'table-name' = 'DB2INST1.PRODUCTS'
);

关键配置说明:

  • connector = 'db2-cdc':使用 Db2 CDC 源;
  • hostname / port:指向 Docker 里的 Db2 服务;
  • database-name:Db2 数据库名(这里是大写 TESTDB);
  • table-name:带 schema 的表名 DB2INST1.PRODUCTS

这个表一旦被定义,就表示 Flink 会:

  • 启动时读取一遍 当前快照
  • 后续持续订阅 Db2 日志,获取 INSERT / UPDATE / DELETE 变更。

2. 定义 Elasticsearch 目标表

es_products 表映射到 ES 的 enriched_products_1 索引:

sql 复制代码
CREATE TABLE es_products (
    ID INT NOT NULL,
    NAME STRING,
    DESCRIPTION STRING,
    WEIGHT DECIMAL(10,3),
    PRIMARY KEY (ID) NOT ENFORCED
) WITH (
    'connector' = 'elasticsearch-7',
    'hosts' = 'http://localhost:9200',
    'index' = 'enriched_products_1'
);

3. 建立同步任务

一句 SQL 把两头连起来:

sql 复制代码
INSERT INTO es_products
SELECT * FROM products;

这条语句一旦提交,Flink 就会启动一个 长跑任务

  • 把 Db2 里 PRODUCTS 表的当前数据同步到 ES;
  • 持续消费 Db2 的 CDC 日志,把后续变更实时写入 ES 索引。

四、在 Elasticsearch / Kibana 中查看数据

此时打开 Kibana:

  • 访问:http://localhost:5601/
  • Stack Management → Index Patterns 中创建一个 enriched_products_1 的 index pattern;
  • 然后在 Discover 里选择该 index pattern,就可以看到从 Db2 同步过来的产品数据了。

也可以直接用 curl 验证:

bash 复制代码
curl -X GET "localhost:9200/enriched_products_1/_search?pretty"

五、修改 Db2 数据,观察 ES 实时变化

接下来我们通过登陆 Db2 容器手动执行几条 DML,看看 Elasticsearch 中的文档是否跟着变化。

进入 Db2 容器并切换到实例用户:

bash 复制代码
docker exec -it ${containerId} /bin/bash

su db2inst1
db2 connect to testdb
db2

然后在 db2 命令行里执行以下 SQL:

sql 复制代码
-- 1)更新一条产品描述
UPDATE DB2INST1.PRODUCTS
SET DESCRIPTION='18oz carpenter hammer'
WHERE ID=106;

-- 2)插入两条新产品
INSERT INTO DB2INST1.PRODUCTS
VALUES (default,'jacket','water resistent white wind breaker',0.2);

INSERT INTO DB2INST1.PRODUCTS
VALUES (default,'scooter','Big 2-wheel scooter ',5.18);

-- 3)删除一条产品
DELETE FROM DB2INST1.PRODUCTS
WHERE ID=111;

理论上你会看到:

  • UPDATE:对应 ES 中同一个 ID 文档被更新(描述字段变成 "18oz carpenter hammer");
  • INSERT:新增两条产品文档;
  • DELETE:对应文档从 ES 中被删除(或者被标记删除,具体看 connector 配置)。

切回 Kibana 的 Discover 页面,刷新一下,就能直观看到这些变更已经被实时"搬运"到了 Elasticsearch。

六、小结与扩展方向

通过这套 Demo,我们完成了一条最小可运行的链路:

Db2(TESTDB/PRODUCTS) → Flink Db2 CDC → Elasticsearch(enriched_products_1) → Kibana 展示

你可以在此基础上做很多扩展:

  • SELECT * FROM products 中加入字段映射、清洗、聚合等实时 ETL;
  • 把多个 Db2 表 join 后再写入一个 ES 索引,形成"宽表"搜索视图;
  • 把 ES 换成 Doris / StarRocks / Kafka 等下游,变成 Db2→实时数仓 / 实时总线 的架构;
  • 把 Demo 中的单机 Flink 集群迁移到生产 Yarn/K8s 环境。
相关推荐
老蒋新思维2 小时前
创客匠人 2025 高峰论谈(11.22-25):AI 智能体重构创始人 IP 打造与知识变现的管理逻辑
大数据·网络·人工智能·网络协议·tcp/ip·重构·知识付费
TDengine (老段)4 小时前
TDengine 字符串函数 TO_BASE64 用户手册
android·大数据·服务器·物联网·时序数据库·tdengine·涛思数据
啊吧怪不啊吧4 小时前
算法王冠上的明珠——动态规划之斐波那契数列问题
大数据·算法·动态规划
源码之家12 小时前
基于Python房价预测系统 数据分析 Flask框架 爬虫 随机森林回归预测模型、链家二手房 可视化大屏 大数据毕业设计(附源码)✅
大数据·爬虫·python·随机森林·数据分析·spark·flask
TDengine (老段)13 小时前
什么是 TDengine IDMP?
大数据·数据库·物联网·时序数据库·tdengine·涛思数据
Apache Flink14 小时前
Flink Forward Asia 2025 城市巡回 · 深圳站
大数据·flink
Hello.Reader14 小时前
Flink DataStream API 打包使用 MySQL CDC 连接器
大数据·mysql·flink
2021_fc14 小时前
Flink入门指南:使用Java构建第一个Flink应用
java·大数据·flink
Hello.Reader14 小时前
Streaming ELT with Flink CDC · Iceberg Sink
大数据·flink