1.  MongoDB CDC to MySQL

从错误日志 The $changeStream stage is only supported on replica sets 可知:MongoDB 的 changeStream 功能(CDC 依赖的核心能力)仅支持「副本集(Replica Set)」架构,而当前连接的 MongoDB 是「单节点(Standalone)」模式,因此 CDC 任务失败。

解决方案:部署 MongoDB 副本集 + 调整 SeaTunnel 配置

MongoDB CDC 必须依赖副本集的 changeStream 能力,因此需要先将 MongoDB 从「单节点」升级为「副本集」,再调整 SeaTunnel 连接配置。

1.1 步骤 1:将 MongoDB 部署为副本集

以下是单节点转换为副本集的最简步骤(生产建议至少 3 节点,演示可单节点模拟副本集):

  1. 修改 MongoDB 配置文件(以 mongod.conf 为例):
    添加「副本集名称」配置,示例:
    replication:
      replSetName: rs0  # 自定义副本集名称,如 rs0 
  2. 重启 MongoDB 服务:
    systemctl restart mongod  # 或根据实际启动方式重启
    
     
  3. 初始化副本集:
    连接 MongoDB 客户端(mongo 或 mongosh),执行初始化命令:
    rs.initiate({
      _id: "rs0",        // 与配置文件中 replSetName 一致
      members: [
        { _id: 0, host: "localhost:27017" }  // 单节点先加入自身
      ]
    })
    
     
    执行 rs.status() 可查看副本集状态,确认节点为 PRIMARY(主节点)。

1.2 步骤 2:调整 SeaTunnel MongoDB-CDC 配置

修改 hosts 为副本集连接 URI(需包含 replicaSet 参数),示例:
source {
  MongoDB-CDC {
    # 格式:mongodb://<host>:<port>/<database>?replicaSet=<副本集名称>
    hosts = "mongodb://localhost:27017/testMcp?replicaSet=rs0"  
    database = ["testMcp"]
    collection = ["testMcp.product"]
    username = stuser
    password = stpw
    schema = {
      table = "testMcp.products"
      fields {
        "_id" : string,
        "name" : string,
        "quantity" : string,
        "price" : string
      }
    }
  }
}
 

1.3 步骤 3:重新执行 SeaTunnel 任务

此时 MongoDB 为副本集架构,支持 changeStream,重新运行任务即可:
./bin/seatunnel.sh --config ./job/mongodb-to-mysql-cdc.conf -e local

2 MongoDB to MySQL(非实时同步)

2.1 步骤 1:生成 JOB 配置

若暂时无法部署副本集,且业务允许非实时增量同步,可改用 SeaTunnel 的 MongoDB 源(基于查询拉取数据,无 CDC 实时性)。示例配置:
注意:官网上支持 DECIMAL 但是实际报错:ErrorDescription:['SeaTunnel' unsupported data type 'decimal' of 'price']
env {
  parallelism = 1
  job.mode = "BATCH"
  checkpoint.interval = 5000
}

source {
  MongoDB {
    uri = "mongodb://127.0.0.1:27017/testMcp"
    database = "testMcp"
    collection = "product"
    schema = {
      table = "testMcp.products"
      fields {
        "_id" : string,
        "name" : string,
        "quantity" : int,
        "price" : DOUBLE
      }
    }
  }
}


sink {
  JDBC {
    url = "jdbc:mysql://127.0.0.1:3306/testMcp?useUnicode=true&characterEncoding=utf8"
    driver = "com.mysql.cj.jdbc.Driver"
    user = "root"
    password = "HkZiWdDba159+-*%"
    table = "product"
    database = "testMcp"  # 新增:指定目标数据库名(与url中的数据库一致)
    fields = ["_id", "name", "quantity", "price"]
    generate_sink_sql = true  # 开启自动生成SQL时必须配置database
    batch_size = 100
  }
}
核心结论:MongoDB CDC 强依赖副本集的 changeStream 功能,单节点无法支持。优先推荐部署副本集 + 调整 CDC 配置;若无法改架构,再考虑非 CDC 的查询式同步。

2.2 步骤2:执行任务

./bin/seatunnel.sh --config ./job/mongodb-to-mysql-jdbc.conf -e local

部分输出:源表有5行数据

2025-09-03 15:30:44,218 INFO  [s.c.s.s.c.ClientExecuteCommand] [main] - 
***********************************************
           Job Statistic Information
***********************************************
Start Time                : 2025-09-03 15:30:42
End Time                  : 2025-09-03 15:30:44
Total Time(s)             :                   1
Total Read Count          :                   5
Total Write Count         :                   5
Total Failed Count        :                   0
***********************************************

2025-09-03 15:30:44,219 INFO  [c.h.c.LifecycleService        ] [main] - hz.client_1 [seatunnel-647792] [5.1] HazelcastClient 5.1 (20220228 - 21f20e7) is SHUTTING_DOWN
2025-09-03 15:30:44,222 INFO  [c.h.i.s.t.TcpServerConnection ] [hz.main.IO.thread-in-1] - [localhost]:5801 [seatunnel-647792] [5.1] Connection[id=1, /127.0.0.1:5801->/127.0.0.1:5991, qualifier=null, endpoint=[127.0.0.1]:5991, remoteUuid=5cc5ab97-9554-472a-b406-4c6ab9f3f8b0, alive=false, connectionType=JVM, planeIndex=-1] closed. Reason: Connection closed by the other side

 

3 Mongodb 与 MySQL 表机构与数据

3.1 Mongod

> db.product.find()
{ "_id" : ObjectId("68b6ec0fa86d08d39b13b690"), "name" : "示例产品1", "quantity" : 100, "price" : 29.99 }
{ "_id" : ObjectId("68b6f09358ba6cc37dd3ac01"), "name" : "示例产品1", "quantity" : 100, "price" : 29.99 }
{ "_id" : ObjectId("68b6f1107c3a4313e2f6f4a1"), "name" : "示例产品1", "quantity" : 100, "price" : 29.99 }
{ "_id" : ObjectId("68b6f1107c3a4313e2f6f4a2"), "name" : "示例产品2", "quantity" : 50, "price" : 19.99 }
{ "_id" : ObjectId("68b6f1107c3a4313e2f6f4a3"), "name" : "示例产品3", "quantity" : 200, "price" : 39.99 }
> 

3.2 MySQL

mysql> desc product;
+----------+--------------+------+-----+---------+-------+
| Field    | Type         | Null | Key | Default | Extra |
+----------+--------------+------+-----+---------+-------+
| _id      | varchar(50)  | NO   | PRI | NULL    |       |
| name     | varchar(100) | YES  |     | NULL    |       |
| quantity | int          | YES  |     | NULL    |       |
| price    | double       | YES  |     | NULL    |       |
+----------+--------------+------+-----+---------+-------+
4 rows in set (0.01 sec)

mysql> 
mysql> 
mysql> select * from product;
+--------------------------+---------------+----------+-------+
| _id                      | name          | quantity | price |
+--------------------------+---------------+----------+-------+
| 68b6ec0fa86d08d39b13b690 | 示例产品1     |      100 | 29.99 |
| 68b6f09358ba6cc37dd3ac01 | 示例产品1     |      100 | 29.99 |
| 68b6f1107c3a4313e2f6f4a1 | 示例产品1     |      100 | 29.99 |
| 68b6f1107c3a4313e2f6f4a2 | 示例产品2     |       50 | 19.99 |
| 68b6f1107c3a4313e2f6f4a3 | 示例产品3     |      200 | 39.99 |
+--------------------------+---------------+----------+-------+
5 rows in set (0.00 sec)

 

 

 posted on 2025-09-03 15:25  xibuhaohao  阅读(10)  评论(0)    收藏  举报