本项目各模块重构前后的差异对比。每个模块一节:对比维度表 + 关键差异展开说明。 目的:为 review / 回归 / 将来 ADR 归档提供"看得见的差异"镜头;入职新人也可以从这里快速把握项目的演进脉络。
| # | 维度 | 老入口 | 新入口 |
|---|---|---|---|
| 1 | 入口文件数 | 5 .sh + 3 .py 调试壳 + 1 config-generator.py = 9(不含独立保留的 gc-generator.py) |
2 对 .sh + .py + cli.py = 5 |
| 2 | 入口组织 | 三层堆叠:multiple-hive → multiple → single |
门面模式:datax-hive-import-starter / datax-hdfs-export-starter 两条独立入口 |
| 3 | 核心语言 | bash 脚本为主,Python 做 ini→json 翻译 | Python 为主,bash 薄壳(≤ 10 行)仅 env 引导 |
| 4 | 参数形态 | -c/-cd/-gc/-gcd/-jc/-jcd 6 种输入 + --override + 脚本内 5 个硬编码数组 |
-ini <file> / -inis <dir> 两种输入 + 8 个选项 |
| 5 | 能力边界 | json 路径暴露给调用方(-c / -jc),用户可能手动管 json |
json 是内部中间产物,conf/datax-json/{job_name}.json 扁平化,调用方不感知 |
| 6 | 核心抽象 | shell for 循环 + 函数 | Python 分层:entry(门面)→ batch(调度)→ runner(执行)+ worker / partition / path_utils / mask / cli 旁支 |
| 7 | 优雅与否 | set -e + command-substitution 静默退出坑;parse_ddl 用 grep "path =" 字面子串(多空格对齐就漏);5 个硬编码数组 + --override 从未激活;__contains__(k) 反 Pythonic |
in / ConfigParser / os.path 标准用法;NamedTuple / 纯函数 / 闭包分层;类型注解;异常抛堆栈 |
| 8 | 死代码 | plugin.py: import pwd 无引用、mysql_reader 顶层 import 已删的 dw_base.database.mysql_utils、5 个 xxx_array=() 空壳、--override case 无作用对象、conf/datax/config/ 前缀剥离(目录已归档 bak)、conf/datax/generated 路径默认值 |
无(单测 47 条覆盖) |
| 9 | Hive 分区管理 | parse_ddl 依赖 ini path = 单空格字面子串、从 path 按 / 切段找 .db 段 |
partition.parse_ini_partition 走 ConfigParser.get('writer', 'path') 正规读;.db 段抽取逻辑同语义但容错更好 |
| 10 | 分区 dt 计算 | START_DATE(单日范围对、多日范围错位 —— 见 kb/90 §2.6 实现建议 5 的坑) |
stop_date - 1 day,和 HDFS writer 注释对齐 |
| 11 | 字段脱敏 | 不支持;需要在 ini 里自己手写 querySql 用 SQL 表达式脱敏 | [mask] 声明式段自动生成 querySql;PG 5 种脱敏(3 静态 month_trunc / md5 / mask_middle + 2 动态 keep_first_{n} / keep_last_{n}),列名白名单防 SQL 注入 |
| 12 | Workers 配置 | 硬编码在 init.sh:13-28(老 m3/d1-d4 列表 + 权重 map) |
外配 conf/workers.ini(新 cdhmaster02/cdhnode01-03) |
| 13 | 日志路径 | 多维派生:${LOG_ROOT_DIR}/datax/${SRC_DST}/${PROJECT_LAYER_ENV}/${DB_ENV}/${GROUP}/${START_DATE}/${JOB_NAME}.log,路径含老 conf/datax/config/ 残留语义 |
扁平化:${LOG_ROOT_DIR}/datax/${dt}/${job_name}.log(对齐 kb/90 §7.2.1) |
| 14 | 日志内容(stdout) | pretty_print 带 ANSI 颜色:NORM_MGT(紫)+ NORM_GRN(绿)+ NORM_RED(红)+ NORM_YEL(黄)分区;驱动常量来自 bin/common/print-constants.sh + dw_base/__init__.py |
Python 原生 print 无颜色(退化);DataX JVM 自身日志输出不变;异常改用 raise RuntimeError 携堆栈 |
| 15 | Tee / 独立日志文件 | bash 层 \| tee LOG(串行)/ > LOG 2>&1 &(并行),shell pipe 天然做到 |
Python 层 subprocess.run(stdout=file_handle),并行模式每任务独立 log 文件;串行模式 stdout 继承父进程、无独立日志文件(需上游 bash 套 tee) |
| 16 | 错误处理 | set -e + exit code 透传、出错位置信息含糊 |
Python Exception + subprocess.returncode,抛 RuntimeError 含上下文(ini 名 / 阶段) |
| 17 | 分布式 | -random + workers.ini 加权随机 + ssh 分发到 worker |
同(待 kb/93 ADR-02 拍板后可砍 ssh 分发,DS worker group 接管) |
| 18 | 字段变换 | 无(需源库做或下游 Spark SQL 做) | ini [mask] 声明式 + mask.py 翻译为 PG querySql 内 SQL 表达式,源库端脱敏(合规硬约束:敏感不出业务库) |
| 19 | 环境依赖 | init.sh 硬编码 USER=bigdata / RELEASE_HOST=m3 / DATAX_WORKERS / PYTHON3_PATH / DATAX_HOME 老路径 |
环境全从 conf/env.sh + conf/workers.ini 读;bootstrap_env() 通过 bash 子进程解析 env.sh 注入 os.environ(Python / Bash 单源) |
| 20 | 测试覆盖 | 0 单测 | 47 条单测(path_utils 5 + worker 6 + partition 7 + runner 5 + batch 7 + entry 5 + cli 3 + mask 9) |
| 21 | 可维护性 | bash 脚本 + 内嵌数组 + 多文件分散,新人上手须看 3+ 脚本理解 multiple-hive → multiple → single 调用链;改动易漏同步;无类型注解;错误信息模糊 |
Python 分层模块职责单一;类型注解 + docstring;47 单测兜底;异常含上下文 |
| 22 | 可扩展性 | 加新 reader 要改 plugin_factory.py 顶层 import 并扩 registry;加新脱敏类型要手写 querySql 或改 plugins/reader/*.py 代码 |
加新脱敏类型只改 mask.py 静态字典一行 / 动态正则一条;加新 ssh 命令子命令只在 cli.py 加 subparser;plugin_factory eager import 未变动(见 kb/90 §2.6 后延 ADR 的"plugin_factory 解耦"低优先级项) |
对比表里新不如老的项:
print 无 ANSI。用户控制台看到的执行日志从带颜色的"分级可读"变成单色纯文本。如要恢复用 colorama 或自己写 20 行 ANSI escape helper 即可,本轮不做| tee。并行模式保留了独立 log 文件。影响面小(DS 调度默认带 stdout 捕获),本轮不做dw_base/datax/ Python 分层共 ~800 行 + 单测 ~600 行workers.ini / env.sh / [mask] 段替代原先散在 shell 脚本 / plugin 代码里的硬编码[mask] 声明式脱敏保证敏感字段源库端处理、敏感原值不出业务库parse_ddl 多日范围分区错位、querySql 模式 column 非 list 的 ClassCastException、plugin_factory eager import 链里死 import 破整条链路等worker.py / runner.py 里 ssh 远端分发逻辑可砍