2024 年 6 月,我接到一个看起来很小的需求:在平台里增加数据集成能力,先支持 MySQL、ClickHouse 同步到 Hive。
如果只看演示效果,这个需求无非是填一张表单,点击运行,然后出现一条任务记录。但真正落到 DataX 上,表单后面是一份层级很深的 JSON。数据库连接、reader、writer、字段映射、并发数和目标表配置散落其中,少写一个括号就无法启动。
第一个版本:先让它跑起来
最初我为两种同步方向分别准备模板,再将请求参数填入模板。这个阶段的目标很朴素:替代人工复制 JSON。
很快,新的问题出现了。
生成成功不代表配置正确。表名可能为空,字段数量可能对不上,ClickHouse 和 MySQL 的 reader 参数并不一样。更麻烦的是,DataX 启动失败时会输出很长的日志,真正有用的原因可能只占其中几行。
于是一个“生成配置”的接口逐渐长出了完整生命周期:
表单参数
↓ 校验、标准化
任务描述
↓ 选择模板
DataX JSON
↓ 再次解析校验
持久化文件
↓ 子进程执行
日志与任务状态
我特意保留了生成后的 JSON 文件。它既是执行输入,也是一次任务的现场快照。线上任务失败时,可以确认当时到底用了哪些字段和参数,而不是拿当前页面配置去猜历史情况。
日志不是越多越好
DataX 会输出统计、速度、脏数据和异常堆栈。全部原样塞给前端没有意义。我做的事情更像一次“降噪”:保留完整日志供排查,同时提取用户最需要的错误摘要。
这里有一个容易被忽略的边界:错误提取不能依赖某一行固定位置。不同插件、不同失败阶段的日志形式并不一致,只能识别相对稳定的标记,并在识别失败时退回完整日志,而不是再制造一个“解析错误”覆盖原始问题。
后来我怎样理解这项工作
DataX 本身早已具备同步能力,我没有发明新的数据搬运引擎。平台真正增加的是一层产品语义:
- 用户描述的是“从哪张表同步到哪里”,而不是 reader 和 writer;
- 系统负责把输入变成可执行配置;
- 每次执行都有文件、状态和日志可以追溯;
- 常见错误在任务启动前就被拦截。
这也是我第一次比较清晰地意识到,所谓平台化,不是给命令行工具套一个页面。它是在工具和使用者之间重新划分责任,把原来依赖个人经验的部分,变成系统能够承担的确定性。