一个 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:3306 和 localhost: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 的数据模型和分区,心里就有底了。