فهرست منبع

docs(kb): 94 新建重构对比文档(首节 DataX 入口 22 项差异)

作为项目各模块重构前后差异对比的聚合点
首节:DataX 入口(2026-04-23 完成),22 维度对比表 + 行为退化说明
  + 收益点概述 + 待讨论项;后续其他模块重构作 §2 §3 加入
不以 datax 命名是为了容纳其他模块(spark 入口 / udf 重组 / ...)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
tianyu.chu 1 هفته پیش
والد
کامیت
9b798c4e35
1فایلهای تغییر یافته به همراه63 افزوده شده و 0 حذف شده
  1. 63 0
      kb/94-重构对比.md

+ 63 - 0
kb/94-重构对比.md

@@ -0,0 +1,63 @@
+# 重构对比
+
+> 本项目各模块重构前后的差异对比。每个模块一节:对比维度表 + 关键差异展开说明。
+> 目的:为 review / 回归 / 将来 ADR 归档提供"看得见的差异"镜头;入职新人也可以从这里快速把握项目的演进脉络。
+
+## 1. DataX 入口重构(2026-04-23 完成)
+
+### 1.1 对比表(22 项)
+
+| # | 维度 | 老入口 | 新入口 |
+|---|---|---|---|
+| 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 解耦"低优先级项) |
+
+### 1.2 行为退化说明
+
+对比表里**新不如老**的项:
+
+- **#14 日志颜色退化**:新入口 Python `print` 无 ANSI。用户控制台看到的执行日志从带颜色的"分级可读"变成单色纯文本。如要恢复用 `colorama` 或自己写 20 行 ANSI escape helper 即可,本轮不做
+- **#15 串行模式日志文件缺失**:新入口串行跑时 stdout 只继承父进程、不单独落 log 文件,需要上游 bash 套 `| tee`。并行模式保留了独立 log 文件。影响面小(DS 调度默认带 stdout 捕获),本轮不做
+
+### 1.3 收益点概述
+
+- **入口数 9 → 5**,调用方学习曲线陡降
+- **测试覆盖 0 → 47**,回归有护栏
+- **代码量**:bin/ 层 shell 脚本 1200+ 行减到 bin/ 层 ≤ 200 行,其余逻辑搬到 `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 破整条链路等
+
+### 1.4 待讨论 / 未收尾
+
+- kb/93 ADR-02 草案(分布式归 DS worker group)正式拍板后,`worker.py` / `runner.py` 里 ssh 远端分发逻辑可砍
+- kb/93 ADR-03 草案(零点漂移决策)实施时迁 kb/12
+- kb/90 §2.6 后延 ADR 低优先级三项(日期范围展开 / plugin_factory 解耦 / 日志颜色恢复可能也要补)
+
+---
+
+## 2. (待补)
+
+---
+
+## 3. (待补)