一、整体环境概览
我们用一份 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 CDC 所需依赖
Flink 这边,需要把 Db2 CDC 和 ES7 连接器的 JAR 丢到 <FLINK_HOME>/lib 下:
flink-sql-connector-elasticsearch7-3.0.1-1.17.jarflink-sql-connector-db2-cdc-3.0-SNAPSHOT.jar
注意:3.0-SNAPSHOT 一般需要自己从 master / release 分支编译,稳定版本才有直接的下载链接。
然后启动一个 Flink 集群(Standalone / Yarn / K8s 都可以),再打开 Flink SQL CLI。
三、用 Flink SQL 打通 Db2 → Elasticsearch
在 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 环境。