从零打通 MySQL → DataX → Doris:Windows 11 + Docker 本地环境搭建全记录

一个 Java 后端开发的数据仓库入门实战笔记。


一、背景

公司用 DataX + Doris 搭数据仓库。我只写过 SpringBoot,对大数据这套东西完全陌生。花了一个周末把 MySQL → DataX → Doris 的第一条同步链路跑通了,记录一下过程,给同样背景的人参考。

二、这些东西分别是干什么的

1. MySQL 和 Doris 的分工

MySQL 管业务(下单、付款),Doris 管分析(报表、排行)。

MySQL 擅长单次少量行的增删改查。当老板要看"上个月各地区销售额排行",一条 SQL 要扫几百万行,MySQL 跑不动,还会拖慢正常的下单接口。Doris 就是为这种扫描大量数据做汇总的场景设计的。

2. 数据怎么从 MySQL 到 Doris

数仓有一套标准的加工流水线,叫 ETL(抽取→转换→加载):

复制代码
MySQL 业务表 → DataX 搬运 → Doris 原样落表(ODS层)→ SQL 清洗(DWD层)→ SQL 聚合(DWS层)→ 报表查询

各层职责:

  • ODS(操作数据层):源表原样搬过来,不改
  • DWD(明细数据层):清洗、去重、关联
  • DWS(汇总数据层):按维度预聚合(按天/按区域的销售额汇总)
  • ADS(应用数据层):直接给报表用的最终结果表

DataX 在这条链里只做一件事:搬运。从 A 读到内存,写到 B,不改数据。配置一个 JSON 文件,指定 reader(从哪读)和 writer(往哪写)就行。

三、环境搭建

1. 总体架构

复制代码
Windows 11 宿主机
├── Docker Desktop
│   ├── mysql-learn     (MySQL 8.0, 端口 3306)
│   ├── doris-fe        (Doris 前端节点, 端口 9030)
│   └── doris-be        (Doris 后端节点, 端口 8040)
└── DataX (本机 Python 3.8 启动)

所有容器在一个自定义 Docker 网络 datax-net 里,互相用容器名通信。DataX 跑在宿主机上,通过 localhost:3306localhost:9030 连数据库。

2. 启动 MySQL

powershell 复制代码
docker network create --subnet=172.19.0.0/16 datax-net

docker run -d --name mysql-learn --network datax-net `
  -e MYSQL_ROOT_PASSWORD=root123 `
  -e MYSQL_DATABASE=test_db `
  -p 3306:3306 mysql:8.0

3. 启动 Doris FE 和 BE

Doris 分两种节点:FE(管理调度)和 BE(存储计算)。学习环境各一个就够了。

powershell 复制代码
# FE
docker run -d --name doris-fe --network datax-net --ip 172.19.0.10 `
  -e FE_SERVERS="fe1:172.19.0.10:9010" -e FE_ID=1 `
  -p 8030:8030 -p 9030:9030 apache/doris:fe-2.1.9

# BE
docker run -d --name doris-be --network datax-net --ip 172.19.0.4 `
  -e FE_SERVERS="fe1:172.19.0.10:9010" -e BE_ADDR="172.19.0.4:9050" `
  -p 8040:8040 apache/doris:be-2.1.9

关键:固定 IP。 容器重启后 IP 会变,BE 失联排查很麻烦。

启动后等 30 秒,验证 BE 存活:

powershell 复制代码
docker exec doris-fe mysql -h 127.0.0.1 -P 9030 -uroot `
  -e "SHOW BACKENDS\G"

Alive: true 即可。

4. 安装 DataX

DataX 是 Python + Java 跑的。官方提供编译好的压缩包,解压即用。

坑点 :Python 3.10+ 不兼容。DataX 的启动脚本用了 imp 模块,Python 3.12 已彻底移除。另装一个 Python 3.8,不改系统 PATH,启动时指定完整路径:

powershell 复制代码
& "C:\Python38\python.exe" datax\bin\datax.py job\job.json

四、打通第一条链路

1. 建表

MySQL:

sql 复制代码
CREATE TABLE orders (
    id           BIGINT AUTO_INCREMENT PRIMARY KEY,
    order_no     VARCHAR(32) NOT NULL,
    user_id      BIGINT NOT NULL,
    product      VARCHAR(100) NOT NULL,
    amount       DECIMAL(10,2) NOT NULL,
    region       VARCHAR(20) NOT NULL,
    status       TINYINT DEFAULT 0,
    create_time  DATETIME DEFAULT CURRENT_TIMESTAMP
);

INSERT INTO orders (...) VALUES (...);  -- 插 10 条测试数据

Doris:

sql 复制代码
CREATE TABLE orders (
    id           BIGINT,
    order_no     VARCHAR(32),
    user_id      BIGINT,
    product      VARCHAR(100),
    amount       DECIMAL(10,2),
    region       VARCHAR(20),
    status       TINYINT,
    create_time  DATETIME
)
DUPLICATE KEY(id)
DISTRIBUTED BY HASH(id) BUCKETS 4
PROPERTIES ("replication_num" = "1");

注意 :学习环境只有 1 个 BE,replication_num 必须设 1,Doris 默认 3 会报错。

2. DataX 任务 JSON

json 复制代码
{
  "job": {
    "setting": { "speed": { "channel": 1 } },
    "content": [{
      "reader": {
        "name": "mysqlreader",
        "parameter": {
          "username": "root",
          "password": "root123",
          "connection": [{
            "jdbcUrl": ["jdbc:mysql://localhost:3306/test_db"],
            "table": ["orders"]
          }],
          "column": ["*"]
        }
      },
      "writer": {
        "name": "mysqlwriter",
        "parameter": {
          "username": "root",
          "password": "root123",
          "writeMode": "insert",
          "connection": [{
            "jdbcUrl": "jdbc:mysql://localhost:9030/test_db?useServerPrepStmts=false",
            "table": ["orders"]
          }],
          "column": ["*"]
        }
      }
    }]
  }
}

这里有一个反直觉的地方 :writer 用的是 mysqlwriter,不是 doriswriter。因为 Doris 兼容 MySQL 协议,DataX 直接用 JDBC 往 9030 端口写就行。useServerPrepStmts=false 必须加,Doris 不支持 MySQL 的预处理语句。

3. 执行

powershell 复制代码
& "C:\Python38\python.exe" datax\bin\datax.py mysql_to_doris_orders.json

日志末尾看到 读写失败总数 : 0 就通了。

五、踩过的坑

1. Docker 内网 IP 宿主机不通

这是最大的坑,绕了最久。

DataX 如果用 doriswriter,它会通过 FE 获取 BE 地址,然后直接 HTTP 连 BE(8040 端口)写数据。BE 注册的地址是 Docker 内网 IP(172.19.0.4),宿主机 Windows 根本连不上。

试过 DataX 也放 Docker 里跑------但 Docker Hub 上的 DataX 镜像(beginor/datax)不带 doriswriter 插件。换 datax_web 镜像,登录卡了半天,进去后发现也没插件。自己挂载插件又遇到 httpclient jar 版本冲突。

最终解决方案:不用 doriswriter,用 mysqlwriter。 Doris 本身就是 MySQL 协议,DataX 通过 JDBC 直接 INSERT,完全不需要走 Stream Load。

2. Python 版本坑

Python 3.14 跑 DataX 直接报错。另装 Python 3.8,不改全局 PATH,启动时指定路径即可。

3. PowserShell 编码

DataX 输出 UTF-8,PowerShell 默认 GBK,中文日志乱码。加上这行:

powershell 复制代码
[System.Console]::OutputEncoding = [System.Text.Encoding]::UTF8

4. Windows 防火墙

IDEA 连 Docker 里的 MySQL 超时。不关防火墙,只开放端口:

powershell 复制代码
New-NetFirewallRule -DisplayName "MySQL 3306" `
  -Direction Inbound -Protocol TCP -LocalPort 3306 -Action Allow

5. MySQL 8.0 认证

JDBC 驱动和 caching_sha2_password 不兼容:

sql 复制代码
ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY 'root123';

6. Doris 容器重启丢数据

Docker 容器没挂 volume,重启后建过的库表全没了。学习阶段忍了,生产环境必须做持久化。

六、总结

复制代码
datax-learn/
├── datax/              # DataX 解压目录
├── jobs/
│   └── mysql_to_doris_orders.json
├── docs/
│   └── stage1-environment-setup.md
└── LEARNING_PLAN.md

作为一个只写过 Java 的后端,第一天把三个组件(MySQL、DataX、Doris)串通,感触最深的是:大数据工具的很多问题不是技术难,而是配置多、厂商杂、网络隔离要自己摸索。

把这条路走通了,后面学 DataX 的增量同步、Doris 的数据模型和分区,心里就有底了。