一、准备工作与整体环境
1. 运行环境假设
- 一台安装了 Docker 的 Linux 或 MacOS 机器;
- 下载好 Flink 1.18.0 ,并解压到目录:
flink-1.18.0/。
2. 使用 Docker Compose 启动依赖组件
我们需要 3 个容器:
- PolarDB-X :存储
products和orders; - Elasticsearch 7.6.0:作为 Flink CDC 的 sink;
- Kibana 7.6.0:可视化 ES 中的数据。
在一个目录下创建 docker-compose.yml:
yaml
version: '2.1'
services:
polardbx:
image: polardbx/polardb-x:2.0.1
container_name: polardbx
ports:
- "8527:8527"
elasticsearch:
image: 'elastic/elasticsearch:7.6.0'
container_name: elasticsearch
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'
container_name: kibana
ports:
- '5601:5601'
volumes:
- '/var/run/docker.sock:/var/run/docker.sock'
启动所有容器:
bash
docker-compose up -d
检查运行状态:
bash
docker ps
浏览器访问:http://localhost:5601,可以看到 Kibana 正常启动,就说明 ES + Kibana 环境 OK。
二、准备 Flink 与 CDC 所需 JAR
1. 下载并解压 Flink
假设你已经下载好 Flink 1.18.0,并解压到:
bash
flink-1.18.0/
2. 准备 Flink CDC & ES Connector
将以下 JAR 放到 flink-1.18.0/lib/ 目录:
flink-sql-connector-mysql-cdc-3.0-SNAPSHOT.jarflink-sql-connector-elasticsearch7-3.0.1-1.17.jar
注意:PolarDB-X 对外兼容 MySQL 协议 ,所以我们直接用 mysql-cdc 连接器即可,不需要单独的 PolarDB-X connector。
三、在 PolarDB-X 中准备业务表和数据
1. 连接 PolarDB-X
PolarDB-X 默认通过 MySQL 协议访问,启动容器后通过以下命令连接:
bash
mysql -h127.0.0.1 -P8527 -upolardbx_root -p"123456"
2. 创建商品表 products 并插入数据
sql
CREATE TABLE products (
id INTEGER NOT NULL AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(255) NOT NULL,
description VARCHAR(512)
) AUTO_INCREMENT = 101;
INSERT INTO products
VALUES (default,"scooter","Small 2-wheel scooter"),
(default,"car battery","12V car battery"),
(default,"12-pack drill bits","12-pack of drill bits with sizes ranging from #40 to #3"),
(default,"hammer","12oz carpenter's hammer"),
(default,"hammer","14oz carpenter's hammer"),
(default,"hammer","16oz carpenter's hammer"),
(default,"rocks","box of assorted rocks"),
(default,"jacket","water resistent black wind breaker"),
(default,"spare tire","24 inch spare tire");
3. 创建订单表 orders 并插入数据
sql
CREATE TABLE orders (
order_id INTEGER NOT NULL AUTO_INCREMENT PRIMARY KEY,
order_date DATETIME NOT NULL,
customer_name VARCHAR(255) NOT NULL,
price DECIMAL(10, 5) NOT NULL,
product_id INTEGER NOT NULL,
order_status BOOLEAN NOT NULL -- Whether order has been placed
) AUTO_INCREMENT = 10001;
INSERT INTO orders
VALUES (default, '2020-07-30 10:08:22', 'Jark', 50.50, 102, false),
(default, '2020-07-30 10:11:09', 'Sally', 15.00, 105, false),
(default, '2020-07-30 12:00:30', 'Edward', 25.25, 106, false);
这里我们构造的是一个非常典型的电商场景:
products保存商品基础信息;orders保存订单信息,并通过product_id关联商品。
四、启动 Flink 集群与 Flink SQL CLI
进入 Flink 目录:
bash
cd flink-1.18.0
启动 Flink 集群:
bash
./bin/start-cluster.sh
浏览器访问 Flink UI:http://localhost:8081,看到 Web UI 说明集群正常。
启动 Flink SQL CLI:
bash
./bin/sql-client.sh
成功后会看到 Flink SQL Client 的欢迎界面。
五、在 Flink SQL 中创建 CDC 源表与 ES Sink 表
1. 打开 Checkpoint
CDC 场景下需要启用 checkpoint 来保证容错与一致性:
sql
-- Flink SQL
SET execution.checkpointing.interval = 3s;
2. 创建 PolarDB-X 源表:orders(通过 mysql-cdc)
sql
CREATE TABLE orders (
order_id INT,
order_date TIMESTAMP(0),
customer_name STRING,
price DECIMAL(10, 5),
product_id INT,
order_status BOOLEAN,
PRIMARY KEY (order_id) NOT ENFORCED
) WITH (
'connector' = 'mysql-cdc',
'hostname' = '127.0.0.1',
'port' = '8527',
'username' = 'polardbx_root',
'password' = '123456',
'database-name' = 'mydb',
'table-name' = 'orders'
);
关键点:
- 虽然数据库是 PolarDB-X,但对外兼容 MySQL 协议,所以使用
mysql-cdc;database-name = 'mydb':要根据实际库名调整(Demo 中假设是mydb);PRIMARY KEY (order_id) NOT ENFORCED:用于 Flink 语义上的主键(Upsert),不强制校验。
3. 创建 PolarDB-X 源表:products
sql
CREATE TABLE products (
id INT,
name STRING,
description STRING,
PRIMARY KEY (id) NOT ENFORCED
) WITH (
'connector' = 'mysql-cdc',
'hostname' = '127.0.0.1',
'port' = '8527',
'username' = 'polardbx_root',
'password' = '123456',
'database-name' = 'mydb',
'table-name' = 'products'
);
有了这两个 CDC 源表,Flink 就可以:
- 启动时读取
orders/products的历史快照; - 后续持续消费 PolarDB-X 的 binlog,接收实时变更。
4. 创建 Elasticsearch Sink 表:enriched_orders
我们希望在 ES 中落一张"宽表":订单信息 + 商品信息一起写入:
sql
CREATE TABLE enriched_orders (
order_id INT,
order_date TIMESTAMP(0),
customer_name STRING,
price DECIMAL(10, 5),
product_id INT,
order_status BOOLEAN,
product_name STRING,
product_description STRING,
PRIMARY KEY (order_id) NOT ENFORCED
) WITH (
'connector' = 'elasticsearch-7',
'hosts' = 'http://localhost:9200',
'index' = 'enriched_orders'
);
这里会在 Elasticsearch 中创建(或使用)名为 enriched_orders 的索引。
六、用 Flink SQL 实时富化订单并写入 Elasticsearch
接下来就是最核心的一步:用 Flink SQL 做 Join,并把结果写入 ES。
sql
INSERT INTO enriched_orders
SELECT
o.order_id,
o.order_date,
o.customer_name,
o.price,
o.product_id,
o.order_status,
p.name,
p.description
FROM orders AS o
LEFT JOIN products AS p
ON o.product_id = p.id;
提交这条语句后,Flink 会启动一个长期运行的 Streaming Job:
- 从 PolarDB-X 捕获
orders和products的快照及增量变更; - 按
product_id = id做实时 Join; - 把 Join 后的富化结果 Upsert 到 Elasticsearch 中的
enriched_orders索引。
七、在 Kibana 中查看实时富化后的订单
1. 创建索引模式(Index Pattern)
打开 Kibana:
- 访问:
http://localhost:5601/app/kibana#/management/kibana/index_pattern - 创建一个 index pattern:
enriched_orders;
2. 查看数据
再打开:
选择刚创建的 enriched_orders index pattern,即可看到已经富化好的订单数据:
- 来自
orders的字段:order_id / order_date / customer_name / price / product_id / order_status - 来自
products的字段:product_name / product_description
这时你就已经打通了:
PolarDB-X → Flink CDC(mysql-cdc)→ Flink SQL Join → ES → Kibana
八、在 PolarDB-X 中修改数据,验证实时同步效果
接下来我们在 PolarDB-X 中执行几条 DML,观察 Kibana 中的数据变化。
1. 插入新订单
sql
-- PolarDB-X
INSERT INTO orders
VALUES (default, '2020-07-30 15:22:00', 'Jark', 29.71, 104, false);
执行后,可以在 Kibana 中看到多了一条新订单记录,且商品信息会根据 product_id = 104 关联到 products 表里对应商品。
2. 更新订单状态
sql
-- PolarDB-X
UPDATE orders
SET order_status = true
WHERE order_id = 10004;
刷新 Kibana 的 Discover 页面,会发现对应订单的 order_status 字段变成了 true。
3. 删除订单
sql
-- PolarDB-X
DELETE FROM orders
WHERE order_id = 10004;
再次回到 Kibana,order_id = 10004 的记录已经从索引中消失(或被标记删除,取决于具体 ES connector 配置)。
整个过程不需要重启 Job,所有变化都在几乎实时地向下游同步。
九、清理环境
实验结束后,记得清理资源。
关闭 Docker 中的 PolarDB-X / ES / Kibana:
bash
docker-compose down
关闭 Flink 集群(在 flink-1.18.0 目录下):
bash
./bin/stop-cluster.sh
十、小结与扩展思路
本篇我们完成了一条完整的链路:
PolarDB-X (存储 orders/products)
→ 通过 mysql-cdc 捕获变更
→ 在 Flink SQL 中做流式 Join
→ 将富化后的订单写入 Elasticsearch enriched_orders 索引
→ 使用 Kibana 实时查看数据变化
在此基础上,你可以继续扩展:
- 换成真实业务库 & 表结构(工资、日志、订单、客户等);
- 在 Flink SQL 中增加过滤、字段清洗、业务衍生字段(如订单状态枚举、货币转换等);
- 把下游从 ES 换成 Doris / StarRocks / Kafka / ClickHouse 等组件;
- 把本地 Docker + Standalone Flink 的实验方案迁移到生产 K8s / Yarn 环境。