Flink CDC 用 PolarDB-X CDC 实时同步数据到 Elasticsearch

一、准备工作与整体环境

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 1.18.0,并解压到:

bash 复制代码
flink-1.18.0/

将以下 JAR 放到 flink-1.18.0/lib/ 目录:

  • flink-sql-connector-mysql-cdc-3.0-SNAPSHOT.jar
  • flink-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 目录:

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 的欢迎界面。

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 做 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:

  1. 从 PolarDB-X 捕获 orders 和 products 的快照及增量变更;
  2. 按 product_id = id 做实时 Join;
  3. 把 Join 后的富化结果 Upsert 到 Elasticsearch 中的 enriched_orders 索引。

七、在 Kibana 中查看实时富化后的订单

1. 创建索引模式(Index Pattern)

打开 Kibana:

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 环境。
相关推荐
方向研究2 分钟前
法国百年房地产
大数据
QY_Research_11 分钟前
全球钥匙联锁系统 市场规模及CAGR5.2%深度分析
大数据·人工智能·物联网·安全·机器人
fox063318 分钟前
预约类平台的责任边界建模:从一个证件办理预约平台的流程设计说起
大数据·数据库·搜索引擎·全文检索·生活
chunyublog20 分钟前
FinalShell 远程连接 Hadoop 三节点集群教程
大数据·hadoop·分布式
龙石数据41 分钟前
龙石 AI 智能体开发平台入选2026全球数据管理峰会数据治理创新实践案例
大数据·人工智能
说实话起个名字真难啊42 分钟前
Git常用小问题笔记
笔记·git·elasticsearch
龙信科技1 小时前
【国内电子数据取证厂商龙信科技】Windows 权限维持型后门分析与防御
大数据·windows·科技·电子数据取证
CAIE研习社1 小时前
CAIE一级有学历和专业门槛吗?报考条件、考试内容与适合人群解析
大数据·人工智能
磁场转动100万匹1 小时前
Spark Core 核心原理:从 RDD 到分布式计算
大数据·分布式·spark
强哥聊算力1 小时前
《算力江湖·DeepSeek》第四集:DeepSeek如何改变中国算力的采购逻辑?
大数据·运维·人工智能·ai·gpu算力