4.4 Writer配置参数:数据目标连接、写入模式、冲突处理


4.4 Writer配置参数:数据目标连接、写入模式、冲突处理

Writer 参数决定「写到哪、怎么写、冲突了怎么办」。和 Reader 相比,Writer 更关心目标端的写入语义,写错模式可能悄悄丢数据。

连接与目标

writer 的 connection 给出目标 jdbcUrl、表名、用户名密码。列顺序要和 column 配置对齐,类型要匹配。HDFS 类 Writer 则给 defaultFS、path、fileType,不涉及 jdbc。

{ "writer": { "name": "mysqlwriter", "parameter": { "username": "etl", "password": "${DST_PWD}", "connection": [{ "jdbcUrl": "jdbc:mysql://h:3306/dw", "table": ["user_summary"] }], "column": ["user_id", "cnt", "updated_at"], "writeMode": "replace", "preSql": ["delete from user_summary where dt = '2024-01-01'"], "postSql": [] } } }

写入模式与冲突

writeMode 常见 insertreplaceupdatereplace 依靠主键/唯一索引覆盖,适合每日全量重算。insert 纯追加,重复跑会产生重复行。我们做「按天分区重算」时,习惯用 preSql 先清当天分区再 insert,比依赖 replace 更可控、可重跑。

写入模式与冲突

前后置 SQL

preSql 在写入前执行,常用来清理目标表或建临时结构;postSql 在写入后执行,可做统计或索引重建。这两个钩子让 Writer 不止是「插数据」,还能编排目标端的小动作。但要小心:preSql 若是 truncate,误配会清空整张表。

我们的红线

任何带 truncate/delete 的 preSql,我们都在脚本里先打印确认目标表名,并禁止在任务里直接 truncate 全表。数据一旦被覆盖清掉,回放成本极高。这条红线在生产环境救过我们不止一次。

写入语义对齐业务

writeMode 选 insert 还是 replace,必须和数据更新语义对齐。每日全量重算的表,用 preSql 先清当天分区再 insert,比依赖 replace 更可控、可重跑。我们严禁任务里直接 truncate 全表,误配会清空整张表,回放成本极高。

模式 语义 适用
insert 纯追加 日志类
replace 主键覆盖 全量重算
preSql 清分区 可控重跑 按天分区

我们的红线是:任何带 delete/truncate 的 preSql,脚本里先打印确认目标表名。数据一旦被覆盖清掉,回放成本极高,这条红线在生产救过我们。

延伸与提醒

日志里周期打印的读写速率,是定位瓶颈的第一手材料。
数据湖贴源层保留原始形态,方便后续 schema 演化。
插件目录名必须和 job.json 的 name 完全一致,大小写都不能错。
Channel 是有界缓冲,填满即触发反压保护内存。
把复杂 join 留在计算引擎,DataX 只做贴源搬运。
Web 平台解决协作与可观测,不提升同步能力本身。
限速不是限制能力,而是给其他任务留出生存空间。
splitPk 的列若分布不均,分片会倾斜,部分 Task 拖慢整体。
任务可重跑幂等,是生产上线前的硬指标。
eswriter 的批量 bulk 写入,比逐条插入快一个数量级。
监控指标和 DataX 日志交叉看,能锁定九成瓶颈。
writeMode 必须和数据更新语义对齐,不能凭感觉选。
调优的本质是在 CPU、网络带宽和磁盘 IO 之间找平衡点,不是堆资源。
机器核数、内存、带宽三者共同决定 channel 的甜点值。
反压机制保护内存,看到任务变慢应去优化下游而非加并发。
关系型 Writer 的批量提交大小,要在往返开销和回滚成本间权衡。
任务的读写速率差,比绝对速率更能说明瓶颈在哪一段。
orc 加 snappy 是 Hive 落地的常见稳妥组合,省空间且查询快。
Redis 同步重跑要防重复 key,靠固定模板才能幂等。
配置进版本库、密码进环境变量,是跨环境复用的基础。
把转换逻辑下推到源库,通常比在 DataX 内部处理更高效。
多租户隔离交给编排层,DataX 保持简单最稳妥。

preSql 先清当天分区,保证任务可重跑。

{ "writer": { "name": "mysqlwriter", "parameter": { "preSql": ["delete from user_summary where dt = '${bizdate}'"] } } }

背景

Writer 参数决定数据最终「怎么进目标、冲不冲突、能不能重跑」。很多「数据对不上」的故障,根子在 Writer 而不是 Reader。

操作:hdfswriter 的写入模式与前后置 SQL

{ "job": { "content": [ { "reader": { "name": "mysqlreader", "parameter": { "connection": [ { "jdbcUrl": ["jdbc:mysql://db:3306/order"], "table": ["t_order"], "splitPk": "id" } ], "column": ["id","user_id","amount"] } }, "writer": { "name": "mysqlwriter", "parameter": { "writeMode": "update", "username": "etl", "password": "secret", "connection": [ { "jdbcUrl": "jdbc:mysql://dw:3306/dw", "table": ["t_order"] } ], "column": ["id","user_id","amount"], "preSql": ["DELETE FROM t_order WHERE dt='20240101'"], "postSql": ["ANALYZE TABLE t_order"], "batchSize": 2048 } } } ], "setting": { "speed": { "channel": 6 } } } }

启动命令

# 重跑前确认 preSql 已清空目标分区,避免新旧数据叠加导致重复 python bin/datax.py job/order_to_dw.json

结果解读

  • writeMode:文本类目标常用 append / nonConflict;关系型目标常用 insert / replace / update
  • preSql/postSql:写入前清空、写入后统计,保证重跑幂等;
  • batchSize:批量提交大小,影响写库吞吐与事务压力;
  • 冲突处理:目标有唯一键时,update 模式按主键覆盖,insert 会报唯一冲突失败。

变式

HDFS 目标的幂等靠 path 分区 + 先删后写;关系型目标靠 preSql 删分区 + writeMode。不同 writer 实现幂等的手段不同,但思路一致——「重跑不产生重复」。

Writer 参数对照

参数 作用 误用后果
writeMode 写入语义 重复 / 失败
preSql 前置清洗 忘清则叠加
postSql 后置统计 影响不大
batchSize 提交批次 过小吞吐低

💡 关键直觉:Writer 的核心职责是「幂等落盘」。一条同步任务能不能放心重跑,几乎全看 Writer 的幂等设计,而不只是「能写进去」。

⚠️ 常见坑:忘记 preSql 清空,任务因网络重试被调度重跑,结果目标表数据翻倍;或 writeModeinsert 撞唯一键失败,应据业务选 update/replace 并确认目标有对应唯一约束。


作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U