92-重构进度.md 33 KB

重构进度

本文档追踪 poyee-data-warehouse 重构任务的执行状态。每次完成一项,在对应 checkbox 打勾并写入完成日期。 与 90-重构路线.md 配套使用:90 说"为什么改、怎么改",92 说"改到哪一步了"。

总览

推进组织方式:2026-04-20 起 kb/90-重构路线.md 改为聚簇 + DAG 视图(A 配置外移 / B dw_base 重组 / C bin 收口 / D 基础设施 / E 业务 SQL / F 老代码删除),阶段号保留作为历史分期,实际推进按聚簇;见 kb/90 §〇 + §八。本 checklist 下方的阶段分节仍保留,便于按阶段对账。

阶段 状态 开始日期 完成日期
阶段 0:知识库梳理 ✅ 已完成 2026-04-14
阶段 1:P0 骨架重命名 🟡 推进中 2026-04-15
阶段 2:P1 硬编码外置 🟡 部分提前完成(B4 骨架 / bin/publish.sh / excel_to_hive 删) 2026-04-20
阶段 3:业务 SQL 从零开发 ⬜ 未开始
阶段 4:测试体系 + 废弃代码清理 🟡 tests 骨架已建 / requirements 精简已完成 2026-04-15
阶段 5:老项目残留删除 ⬜ 未开始

当前所处阶段:主线阶段 1(P0 骨架)推进中;阶段 2 / 4 部分先导项随聚簇 B4 提前完成


阶段 0:知识库梳理 ✅

  • 项目架构文档 00-项目架构.md
  • 运行环境 01-运行环境.md
  • 权限与账号 02-权限与账号.md
  • 业务流程 10-业务流程.md
  • 数据资产 11-数据资产.md
  • 数仓分层与建模 20-数仓分层与建模.md
  • 命名规范 21-命名规范.md
  • 指标体系 22-指标体系.md
  • 标签体系 23-标签体系.md
  • 开发规范 30-开发规范.md
  • 重构路线 90-重构路线.md
  • 项目根 CLAUDE.md 指向 kb

阶段 1:P0 骨架重命名

目标:让新项目结构立起来,老项目代码可以正常运行不受影响。

  • tendata/ 目录改名为 dw_base/(2026-04-15)
  • 全局替换 from tendata / import tendatafrom dw_base / import dw_base(2026-04-15,102 个文件)
  • 全局替换 SQL 中的 ADD FILE tendata/...ADD FILE dw_base/...(2026-04-15)
  • 全局替换 zip -qr tendata.zip tendatazip -qr dw_base.zip dw_base(2026-04-15,spark_sql.py f-string 形式已手工修正)
  • 全局替换 addPyFile('tendata.zip')addPyFile('dw_base.zip')(2026-04-15,publish.sh 同步更新)
  • 全局替换路径正则 re.sub(r"tendata-warehouse.*", ...) → 使用新项目名(绑定仓库改名;2026-04-20 三批老业务清理后残留进一步缩小到 dw_base/utils/ 剩余文件、bin/doris-*-starter.py 等;diff_utils.py / polling_scheduler.py / drop_*.py / spark/udf/customs/* 的字符串字面量已随删除一并清零)
  • 排查 tendata_corp 等数据库名/表名引用,确认不要误替换(2026-04-15,已确认保留:tendata_corptendata_bigdata256!ent_tendata_interfaceapi.tendata.cn
  • 新建 jobs/ 目录 + jobs/{raw,ods,dim,dwd,dws,tdm,ads}/ 子目录(2026-04-15,已放 .gitkeepdim/ 为顶层独立分层)
  • 新建 manual/ 目录 + 5 个子目录(ddl/backfill/fix/adhoc/archive/)(2026-04-15,已放 .gitkeepmanual/ddl/ 是所有 DDL 的唯一来源)
  • 项目仓库改名 tendata-warehouse-releasepoyee-data-warehouse同步改名 .idea/tendata-warehouse-release.iml.idea/poyee-data-warehouse.iml 并更新 .idea/modules.xml 引用)
  • 更新 publish.sh 中的部署路径与项目名
  • 实现 bin/csv-to-hdfs-starter.py:本地 CSV → gzip(可选,大文件才压缩)→ hdfs dfs -put 到暂存区 → 调用 SparkSQL 执行 jobs/raw/{域}/{表}.sql(含 USING csv 临时视图 + INSERT OVERWRITE)→ 清理暂存。任务定义采用 SQL 格式(参见 00-项目架构.md §9.3 模板)
  • 验证:在测试集群跑一次 bin/spark-sql-starter.py 样例,import 和 Spark 环境初始化能过
  • 验证:在测试集群跑一次 bin/datax-single-job-starter.sh 样例,ini→json 生成能过
  • 验证:bin/csv-to-hdfs-starter.py 用一个样例 CSV 跑通 raw 层入仓

完成判定:老项目 launch-pad 下的某个样例作业,在改名后的 dw_base/ 基础上能跑通(import 和运行不报错)。

阶段 2:P1 硬编码外置

目标:消除对老环境(alvis 用户、/home/alvis/release 路径、硬编码的 worker 列表)的代码耦合。

  • 新建项目根 .gitignore(清单与注意事项见 90-重构路线.md §2.4)
  • 建立 conf/env.sh(Shell 环境变量)
  • 建立 conf/env.py 或 Python 读 env.sh 的桥接
  • 建立 conf/workers.ini(DataX Worker 列表 + 权重 map,整体迁出 bin/common/init.sh:18-31
  • 建立 conf/alerter.ini(企微 Webhook,入库;格式见 90-重构路线.md §2.1)
  • dw_base/__init__.py 瘦身(拆分初始化逻辑,见 90-重构路线.md §3)— 必须先做,下面 spark-defaults 依赖瘦身后的 PROJECT_ROOT_PATH
  • 建立 conf/spark-defaults.conf(Spark 全局默认参数,Spark 原生格式,见 90-重构路线.md §2.3)
  • 改造 dw_base/spark/spark_sql.py:构造函数 fall back 到 conf;实现 L1(conf) < L2(SQL 内 SET,仅 spark.sql.* 系生效) < L3(命令行 -sc / 构造函数传参) 三级覆盖
  • 验证:同一条 SQL 在无 SET、有 SET、命令行 -sc 三种场景下 spark.conf.get(...) 返回值符合优先级预期
  • 验证:SET spark.executor.memory=Xg 不会影响已启动 executor(文档里说清楚这条限制)
  • RELEASE_USER="alvis"RELEASE_USER="bigdata" 并迁入 conf/env.sh
  • RELEASE_ROOT_DIR="/home/alvis/release"/home/bigdata/release 并迁入 conf/env.sh
  • DATAX_WORKERS=(m3 d1 d2 d3 d4) + 权重 map 迁入 conf/workers.ini
  • 删除 whoami == RELEASE_USER 分流,LOG_ROOT_DIR 单值 ${HOME}/log 放入 conf/env.sh(见 90-重构路线.md §7.2.1)
  • 日志路径统一模板 ${LOG_ROOT_DIR}/{module}/{dt}/{file}.log(3 层)
  • 实现 log_path(module, dt, file) 工具函数(Python / Shell 各一份,单一来源)
  • 企微 Webhook Key 从 alerter_constants.py 移入 conf/alerter.ini(钉钉已于 2026-04-20 全部删除,不再迁移)
  • DataX 入口收口为两条命令(暂称 datax-import / datax-export命名待确认;见 90-重构路线.md §2.6)
  • 导入命令实现分区管理(-skip-exist / -force-overwrite / -skip-partitions
  • 导出命令实现源 HDFS 路径探测(-src-check / -skip-missing
  • bin/datax-gc-generator.py 从零重写:定位为参考模板生成器from=pg to=hdfs,输出到开发者本地 workspace/{yyyymmdd}/{name}.ini,该目录被 .gitignore 排除、不入仓;开发者裁剪后把成品提交到 jobs/raw/{domain}/),不再生成 DDL(见 90-重构路线.md §2.7)
  • .gitignore 增加 workspace/ 行(见 90-重构路线.md §2.4 清单)
  • 废弃并删除 mysql_utils/MySQLDataSource/MySQLReader.generate_hive_ddl*/convert_mysql_column_types(见 §2.7 拆除清单)
  • HDFS HA 自检(前置决策):2026-04-18 新 CDH 环境实测:HADOOP_CONF_DIR 未设 + /opt/datax 无预置 hdfs-site.xml;手动 export HADOOP_CONF_DIR=/etc/hadoop/conf 后跑 DataX 仍 UnknownHostException: nameservice1。结论:HADOOP_CONF_DIR 对 DataX 无效(datax.py 不把 conf 目录入 classpath),锁定走 Path B
  • 改造 HDFSDataSource:覆写 get_datasource_dict()[hadoop_config] 整节作为 dict 塞进 ds_dict['hadoopConfig'](2026-04-18)
  • 清理 dw_base/__init__.py:16 死代码 os.environ['HADOOP_CONF_DIR'](2026-04-18,实测对 DataX JVM 无影响)
  • HDFS 数据源 ini 新建:按新 schema 运维补齐 datasource/hdfs/{env}/*.ini(prod 带 [hadoop_config];dev/test 只写 [base] defaultFS
  • HA 回归测试:真实 HA 集群 + 单 NN 集群 + 主备切换三场景
  • DataX 速率配置外移conf/datax-speed.ini 定义分时速率档;dw_base/datax/job_config_generator.py:60-67 硬编码替换为读 conf(见 90-重构路线.md §2.9)
  • 新建 manual/imports/ + manual/exports/ 目录(按日期 {yyyymmdd}/ 组织一次性任务)

阶段 3:业务 SQL 从零开发

目标:按新分层架构填充 jobs/ 下的真实业务 SQL,与老 launch-pad/ 零关联。

  • 梳理首批待入仓业务表(按 11-数据资产.md
  • jobs/raw/ 首批 DataX ini(按业务域分目录)
  • jobs/ods/ 首批贴源 SQL
  • jobs/dwd/ 首批明细 SQL
  • jobs/dws/ 首批汇总 SQL
  • jobs/tdm/ 首批主题模型 SQL
  • jobs/ads/ 首批应用层 SQL + 导出 ini
  • 在 DolphinScheduler 中配置工作流,贯通新链路

阶段 4:测试体系 + 废弃代码清理

  • 建立 tests/ 目录骨架(见 90-重构路线.md §6)
  • UDF 单测首批
  • DataX 配置生成单测
  • __contains__in 全局替换
  • 删除废弃空模块和注释代码
  • 重新实现 Hive HDFS 小文件合并工具:原 dw_base/utils/hive_file_merge.py(2026-04-20 随老业务批清理一并删除)提供 alter table ... partition (...) concatenate 压实能力,但硬编码了老 HiveServer 连接 / cts_*_ex/_im 表名规则 / mirror_country 过滤。新版需通用化:HiveServer 连接从 conf/ 读取、表过滤参数化,剥离业务命名假设
  • 重写告警模块:老钉钉告警文件(dingtalk_* / ent_interface_dingtalk* / country_count_dingtalk / spark_parse_json_to_hive 里的 dingtalk() / bin/dingtalk-work-alert.sh)已于 2026-04-20 全部删除;新项目不再使用钉钉,Webhook Key 走 conf/alerter.ini(见 90-重构路线.md §2.1
  • 重新实现分区保留工具:老 dw_base/scheduler/drop_partitions.py + drop_daily_full_snapshot_tbls.py(2026-04-20 删除)提供"按表清理超期分区,保留最近 N 天 + 例外 dt"能力。前者硬编码海关 cts_{mgdb}_{catalog} 表名 + mg_count_monitor 元表,后者元表驱动(daily_full_snapshot_tblsdb/tbl/days)模式更通用。新版采用元表驱动 + 保留天数参数化 + 例外 dt 白名单,不绑业务表名;新目录可能不叫 scheduler(按 N 天清分区不是调度职责,更像 ops/maintenance/
  • Spark / HMS 侧 Ranger Hive 策略验证(低优先级,见 90-重构路线.md §7.5)
  • 精简 requirements.txt(2026-04-15 提前完成:48 行 → 10 个强依赖,老清单备份到 requirements.txt.bak 并逐行打标)

阶段 5:老项目残留删除

前置条件:阶段 3 的业务 SQL 在生产稳定运行至少一个完整周期,且 DS 工作流已完全切换到 jobs/

  • 确认 DS 工作流已无对 launch-pad/ 的引用
  • 删除 launch-pad/ 整个目录
  • 删除其他已确认废弃的老文件

变更记录

日期 变更 操作人
2026-04-14 初始化进度文档,阶段 0 知识库梳理完成
2026-04-15 90-重构建议.md 更名 90-重构路线.md;新增 his 快照 + dim 顶层分层;manual/ddl/ 作为 DDL 唯一来源(migration 模式);精简 requirements.txt(提前完成阶段 4 一项);新增 Spark 配置三级覆盖路线(L1 conf/spark-defaults.yaml / L2 SQL SET / L3 命令行 -sc,阶段 2 任务)
2026-04-15 阶段 1 模块重命名:tendata/dw_base/(目录 + 102 个文件的 import / SQL ADD FILE / zip 打包 / addPyFile / publish.sh);跳过项:tendata-warehouse 正则(待仓库改名)、tendata_corp 等业务库名、ent_tendata_interface topic、api.tendata.cn URL
2026-04-15 阶段 1 目录骨架:新建 jobs/{raw,ods,dim,dwd,dws,tdm,ads}/manual/{ddl,backfill,fix,adhoc,archive}/,均放 .gitkeep 占位
2026-04-15 sql_style.xml 从项目根移入 kb/30-开发规范.md §4.2 补 IDE 格式化导入说明、关键风格表与"不对齐 AS"理由
2026-04-15 新增 .gitignore 计划(90-重构路线.md §2.4 + 阶段 2 checklist),含 .idea/ / .claude/ 部分 ignore 策略、dw_base.zip 构建产物、conf/alerter.conf 敏感项;阶段 1 仓库改名 checklist 追记 .iml 同步改名
2026-04-18 sql_style.xmlkb/ 移入 conf/(IDE 配置不算文档);同步更新 kb/README.md 索引、kb/30-开发规范.md §4.2.1 路径引用、移除 kb/90-重构路线.md §5.1 对应待办行
2026-04-18 kb 文档整理:zhu_tianyutianyu.chu00-项目架构.md 2 处负责人注释);kb/inbox/ 4 份草稿整合完毕 —— 标签服务演进路线.md23-标签体系.md §6 100% 重复直接删除;dwd明细粒度设计原则.md 并入 20-数仓分层与建模.md §5.5;hive数据类型映射.md 并入 20-数仓分层与建模.md §8.4(ES→Hive 占位待补);业务库同步方案.md 独立成文为 kb/12-同步方案.md 并入 README 索引
2026-04-18 02-权限与账号.md §1 补齐 PySpark 鉴权路线(链路 B):Unix 账号身份 + Ranger UserSync 同时同步 LDAP / Unix group;HS2 doAs 仅链路 A 生效;补漏编号 1 并新增"身份(Who)"条目
2026-04-18 架构框图重排:01-运行环境.md §1 大数据平台全景、20-数仓分层与建模.md §2 分层 × 维度侧柱、00-项目架构.md §5 分层架构图 —— 统一"单层单行 + 右侧 DIM 侧柱"样式,按"中文字符宽 2 / ASCII 宽 1"严格对齐;同步修复三文档数据流 ASCII 尾巴的 orphan 和空行
2026-04-18 02-权限与账号.md §2 Mermaid 时序图补齐链路 B(PySpark → HMS + Ranger Hive Plugin → NameNode + Ranger HDFS Plugin → HDFS,身份=Unix 账号,无 doAs)
2026-04-18 反转两条决策:(a) manual/ddl/ 目录组织从"扁平存放"→ 按 {layer}/{domain}/ 分子目录;(b) jobs/{layer}/{domain}/ 下 SQL 从"一张目标表一个 .sql"→ 简单表仍单文件,多步表{表名}/{表名}-{NN}-{描述}.sql 子目录(99 为最终 insert),区分"可复用中间结果应升层"和"单目标加速 tmp 表"两种语义;同步更新 00-项目架构.md §9.1/§9.2/§9.5 文件命名速查表
2026-04-18 90-重构路线.md 新增 §2.6 DataX 入口收口为 datax-import + datax-export、§2.7 datax-gc-generator 从零重写(仅 PG→HDFS,不再生成 DDL)、§2.8 HDFS defaultFS 统一 nameservice;§2.1 workers 行追记"权重 map 一起迁";§7.2.1 反转"删除 whoami 分流"→"保留分流 + 目的地改为 {module}/{dt}/{file}.log"
2026-04-18 manual/ 新增两个子目录语义:manual/imports/{yyyymmdd}/(一次性入仓)+ manual/exports/{yyyymmdd}/(一次性出仓),同步更新 00-项目架构.md §1 目录树 / §9 manual/ 用途表 / §9.5 文件命名速查
2026-04-18 修正 90-重构路线.md §2.8 关于 HDFS nameservice 的表述:代码侧零特殊处理(dw_base/datax/datasources/hdfs_data_source.py:8,21 只把 defaultFS 当不透明字符串透传),nameservice 解析完全靠 DataX worker 节点的 Hadoop 客户端 + hdfs-site.xml;仓库内无 HADOOP_CONF_DIR export
2026-04-18 90-重构路线.md §2.7 改写 datax-gc-generator 定位为参考模板生成器(不是"一键出可用 ini"),产物落 manual/imports/{yyyymmdd}/ 供开发者按需裁剪字段 / 加 WHERE / 调分区;§2.6 datax-import / datax-export 名称标注"命名待确认"
2026-04-18 30-开发规范.md 新增 §4.4 Git 提交信息(Conventional Commits):type 白名单(feat/fix/docs/refactor/perf/test/chore/style/build/ci/revert)、scope 约定({层}/{域} 或模块名)、标题 ≤ 50 字符、破坏性变更 ! + BREAKING CHANGE: 正文约定
2026-04-18 新增 workspace/ 概念:开发者本地草稿区(datax-gc-generator 输出的参考模板 / 临时 SQL 调试),被 .gitignore 排除、永不入仓。同步更新 90-重构路线.md §2.4 .gitignore 清单增加 workspace/ 行、§2.7 datax-gc-generator 输出目的地从 manual/imports/ 改为 workspace/{yyyymmdd}/{name}.ini;并明确 workspace/ vs manual/imports/ 分工
2026-04-18 修正 §2.8:原"把 defaultFS 换 nameservice 就算支持 HA"是错的;DataX HA 必须在 json 里同时提供 defaultFS + hadoopConfig 块(否则无法把 nameservice 解析为具体 NameNode)。ini schema 升级:新增 ha_enabled + [hadoop_config] 节,key 照搬 hdfs-site.xmlHDFSDataSource 需覆写 get_datasource_dict()reader/writer 两侧代码不用改(靠 load_data_source() 自动注入)
2026-04-18 新增 §2.9:DataX 速率控制从 job_config_generator.py:60-67 的分时硬编码(0750-1900 走 10ch×10MB、其它走 6ch×256MB)外移到 conf/datax-speed.conf,按时间段分档;默认值保持向后兼容;在 conf 头注释里补"白天避开业务高峰"的动机
2026-04-18 排查"运维写死 nameservice"实现:全仓 grep HADOOP_OPTS / -Dfs. / 自定义 hdfs-site.xml 写入等全部零命中;现存 conf/bak/.../hdfs-*.ini 只有 defaultFS 一行。仓库零实现。
2026-04-18 修正早先文档误述:dw_base/__init__.py:16 实际上有 os.environ['HADOOP_CONF_DIR'] = '/etc/hadoop/conf'(原 2026-04-18 changelog 早条说"仓库内无 HADOOP_CONF_DIR export"不准确)
2026-04-18 §2.8 改造降级为"条件触发"(第三轮修正):用户提供老项目真实生产 json 样例显示只写 defaultFS(无 hadoopConfig)也能跑 HA —— 说明老 worker 节点 hdfs-site.xml 配置完整,hadoopConfig可选覆盖而非 HA 必要条件。前两轮论断("必须加 hadoopConfig"、"运维把 xml 写死单 NN")都被推翻。§2.8 加"新环境 HDFS HA 自检清单"(echo $HADOOP_CONF_DIR / grep xml HA keys / hadoop fs -ls hdfs://nameservice1/),三项全过则整节改造不做;仅任何一项失败才启动 ini schema 升级 + HDFSDataSource 改造。92 阶段 2 checklist 相应改为"自检前置 + 条件触发"4 条子项
2026-04-18 §2.8 锁定 Path B(第四轮,实测决定):新 CDH 环境三连实测(json 含/不含 hadoopConfig × HADOOP_CONF_DIR 设/不设),结论:对 DataX JVM,仅 json 的 hadoopConfig 块有效,HADOOP_CONF_DIR 无效(datax.py 不把 conf 目录入 classpath,与 hadoop 命令行不同)。老项目能纯 defaultFS 跑通最可能是老运维把 hdfs-site.xml 塞进了 DataX classpath 目录,新环境 /opt/datax 没这类预置文件。改造要点:(a) HDFSDataSource.get_datasource_dict()[hadoop_config] 整节注入 hadoopConfig;(b) 删除 dw_base/__init__.py:16 os.environ['HADOOP_CONF_DIR'] 死代码。简化 §2.8 文本:去掉 ha_enabled 开关(用 [hadoop_config] 节存在性代替)、去掉自检决策树(已决定)、去掉"运维手工改 IP"误记
2026-04-20 §7.2.1 再次反转:删除 whoami == RELEASE_USER 分流,LOG_ROOT_DIR 改为单值默认 ${HOME}/log 并保留在 conf/env.sh(外配后期可改)。理由:$HOME 天然按用户隔离(bigdata/个人用户家目录不同),代码判断是多余一层;bigdata 本身就是专属调度账号,其 $HOME 即是生产日志合法归宿,不需要系统级 /opt/data/log 那条路。同步更新 90-重构路线.md §7.2.1(核心段)+ §2.1 硬编码表行 + §2.4 env.sh 草稿 + 00-项目架构.md §6 部署段 + 92 阶段 2 checklist
2026-04-20 老业务耦合代码第二批清理(重构计划外):在 UDF/模块独立化讨论中顺带盘点 dw_base/ 子模块,决定 16 文件批量删除:整目录删 3 个——oss/(oss2_util.py + init,新业务不需要对象存储)、scheduler/(polling_scheduler / drop_partitions / drop_daily_full_snapshot_tbls 三业务文件,前者绑死老 Mongo 轮询、后两者按 N 天清分区的能力已在阶段 4 记录重写任务)、hive/(hive_utils + hive_constants;hive_utils 中 get_hive_create_table_ddl* 零引用 + 依赖 COLUMN_NAME_COMMENT_DICT 老业务字段字典、DDL 生成器整体不重建;get_hive_database_name / get_hive_table_prefix 两个命名约定函数语义已在 kb/21-命名规范.md 有规则,不重建代码,后续 bin/datax-gc-generator.py 从零重写时按新约定实现);utils/ 删 7 文件——data_distinct / diff_utils / excel_to_hive_utils / hive_diff_database / hive_to_excel_utils / pdt_check_table / pdt_check_table_multis,全部零外部引用 + 强业务耦合(硬编码 tendata 路径 / 老集群 IP 192.168.30.3 / 中文表名拼音转换 / 海关 cts_* 表名模式)。连带效应bin/datax-gc-generator.py:26 import hive_utils 成破损 import,由 90-路线 §2.7 "从零重写" 任务覆盖,不单独修复。阶段 4 新增任务:重新实现分区保留工具(元表驱动 + 参数化天数,目录可能不叫 scheduler)。CLAUDE.md 规则追加:"空模块直接删"原则首次执行延后(elasticsearch/flink/ml/validation/common/ 暂留,后续更细粒度规整)
2026-04-20 老业务耦合代码批量清理(重构计划外):排查 tendata 残留时发现一批与 tendata_corp / ent_tendata_interface / DolphinScheduler / 钉钉告警强耦合的存量文件,逐项核对后批量删除 40 个文件 + 精简 1 个:老业务模块 34dw_base/scheduler/get_oldmongo_* ×5、dingtalk_* / ent_interface_dingtalk* / country_count_dingtalk / mg_company_alias_init ×8、mg2es/ 整目录 13 文件;dw_base/ds/ 整目录 4 文件;dw_base/spark/udf/spark_read_hive_columns_cnt.pydw_base/utils/tid_utils.pydw_base/spark/td_spark_init.py(老同事 xunxu 所写未被调用);bin/hive-exec.sh),级联清理 6dw_base/spark/udf/spark_id_generate_udf.py + dw_base/spark/udf/enterprise/unique/spark_tid_match_udf.py 依赖已删 tid_utilsdw_base/utils/hive_file_merge.py + dw_base/utils/spark_parse_json_to_hive.py 依赖已删 mg2es/钉钉告警;bin/hive-exec-job-starter.py 调用已删 hive-exec.shbin/dingtalk-work-alert.sh),精简 1dw_base/spark/udf/spark_mmq_udf.py 从 530 行裁到 4 个数据类型转换函数(phone/domain/website/statname 等场景相关 UDF 与 Mongo 相关逻辑全删)。同步更新:00-项目架构.md(移除 td_spark_init / DS 相关条目)、90-重构路线.md(钉钉 + 企微 Webhook 合并表述、删除 DS API 行、§5.2 依赖清理清单标记提前完成)、92-进度.md 阶段 1 第 6 行 re.sub checklist 更新残留范围(~15 处)。阶段 4 新增两项任务:(1) 重新实现 Hive HDFS 小文件合并工具(通用化连接 / 剥离 cts_*_ex/_im 表名假设);(2) 重写告警模块(弃钉钉走 conf/alerter.ini Webhook)
2026-04-20 pyspark 入 requirements.txt(反转 2026-04-15 "不写进" 决策):实际开发流程是 PyCharm SSH 到服务器用 bigdata 用户的 Python 解释器,该解释器 site-packages 只有 findspark==2.0.1,真正的 pyspark 在 CDH $SPARK_HOME/python/ 下不被索引 → PyCharm 静态索引红线 + 本地 pytest 失败。解法:pyspark==2.4.0requirements.txt(版本对齐 CDH 6.3.2 parcel 自带 Spark 2.4.0,见 requirements.txt.bak:45 + kb/01-运行环境.md:64);运行时仍靠 findspark.init() 指向集群 $SPARK_HOME/python/,同版本双轨不冲突。同步 kb/90-重构路线.md §7.1 KEEP 行放回 pyspark + 末句机制改写
2026-04-20 UDF 提升为顶层模块(重构计划外)dw_base/spark/udf/dw_base/udf/。动机:UDF 是独立能力域(后续会高频扩展、需本地单测),不应锁死在 spark/ 子树里。联动:dw_base/__init__.py:27 常量、bin/spark-sql-starter.py + bin/excel_to_hive.py 文件头 SQL 样例注释、dw_base/udf/common/spark_common_udf.py 模块 docstring、kb/00-项目架构.md(目录树新增 udf/ 行 + 模块职责表 + Mermaid 节点)、kb/23-标签体系.md §5 bitmap UDF 注册路径。bin/spark-sql-starter.py:172-173 用的是常量自动生效
2026-04-20 修正 §7.1 pyspark 误记:前期文档把 pyspark 列进强依赖 KEEP 行 + "pyspark 2.4.0 固定" 一句,均与真实的 requirements.txt 不符。真实机制:findspark==2.0.1 运行时定位 CDH 集群已装 PySpark,版本随集群走,客户端不固定也不入 requirements.txt。kb/90 §7.1 表格 KEEP 列去 pyspark + "后续事项"末行改为 findspark 机制说明
2026-04-20 UDF 模块重组(重构计划外):独立 dw_base/spark/udf/ 目录结构为 common/(通用 UDF,SparkSQL 入口自动 ADD FILE 注册)+ business/(业务专用 UDF,SQL 中按需 ADD FILE 加载)两类。(a) 6 份源文件(根 spark_common_udf.py 24 函数 + spark_json_array_udf.py 23 函数 + spark_mmq_udf.py 3 函数 + customs/cts_common.py + product/escape_udf.py + enterprise/spark_eng_ent_json_array_append_udf.py)通读 + 去重 + 业务耦合剥离后,合并为单文件 common/spark_common_udf.py(500 行 40 函数,分 JSON / Array / String / Numeric-Date-Hash / Cross-type-converters 5 段)。单文件方案而非按类型拆分,理由:跨类型转换函数(json2str / arr2json / str2map 等约 9 个,占 20%+)没有明确归属,强行分只会制造边界争议。(b) 清理 dw_base/spark/udf/ 下所有老业务 UDF 子目录与根级业务文件共 60 个:整目录删 contacts/ / customs/ / enterprise/ / product/ / productApplication/ / test/;根目录删 spark_eng_ent_name_clean.py / spark_india_format_phone_udf.py / solr_similar_match_udf.py / main_test.py 以及 3 份源 UDF 文件。(c) dw_base/__init__.py:27 COMMON_SPARK_UDF_FILE 常量路径由 dw_base/spark/udf/spark_common_udf.py 改为 dw_base/spark/udf/common/spark_common_udf.pybin/spark-sql-starter.py:172-173 两处 usage 靠常量传递自动生效)。(d) 删除老 dingtalk_* / mg2es 级联清理中没赶上的 UDF 业务耦合文件在此批统一清零。business/ 目录暂为骨架,后续真正出现新业务 UDF 时按需补
2026-04-20 删除空壳模块 ml/ / elasticsearch/ / flink/ / validation/(反转 2026-04-20 早先"暂留"记录):4 个目录下均只有 56 字节空 __init__.py,零 import / 零内容,保留无意义;2026-04-20 UDF 模块重组 changelog 末尾"暂留"一句是误记。git rm -r 一批清零。同步 kb/90-重构路线.md §5.1 从废弃代码表中移除这 4 行并加指向本条 changelog 的尾注。dw_base/common/alerter_constants.py / config_constants.py / container.py / template_constants.py 非空保留,不在本批
2026-04-20 删除 dw_base/database/mongodb_utils.py + kb/90 §5.1 档案化改造:(a) mongodb_utils.py 184 行真实内容仅 MongoDBHandler 薄类 19 行(吃 url/port/user/pwd 拼 URI 实例化 MongoClient),其余 165 行全是公司名→Mongo/ES 查询 + TF-IDF 关键词抽取 + 三段老集群 dds-m5e* 连接串注释。grep 零外部引用。新项目若需连 Mongo 一行 MongoClient(uri) 即可,薄包装无保留价值。(b) §5.1 原表两行实际状态:mongodb_utils.py = 本次删除;conf/datax/ 下老项目遗留 ini/datasource = 项目初始化 8d2ade5 时已整体挪入 conf/bak/datax/{config,datasource}/ 并由 .gitignore:6 conf/bak 拦截,早已完成但没画勾。(c) §5.1 改造为"待清理表(当前为空)+ 历史档案表(完成项留档)"双表结构,空壳模块 4 行 + 本次 mongodb_utils + conf/datax 挪 bak 三项入档案。尾注说明:代码里残留的 conf/datax/config/ replace 死逻辑 + conf/datax/generated 默认值属于 §2.x 路径硬编码清理(改名 conf/datax-json/),不在本节范围
2026-04-20 alerter + datax-speed 扩展名统一为 .ini + alerter 口径统一为"入库":(a) conf/alerter.confconf/alerter.ini + 从 gitignore 改为入库;反转 2026-04-15 changelog(line 139)当时记的 .conf + gitignore 口径。理由:项目 conf/ 全部 ini + 代码侧 configparser 使用 10+ 次 + PyYAML 在 requirements 但零 import yaml(躺尸依赖)→ ini 是事实标准;webhook key 低敏(最多被拿去发垃圾消息,非账密级)+ 部署靠 git pull,gitignore 会让 bigdata / DolphinScheduler 拉不到配置。结构:[common] url_prefix + [channels] ba/dcp/etl/skb/realtime = <key>。(b) conf/datax-speed.confconf/datax-speed.ini,同一口径收敛,消除 .conf/.ini 混用。同步点:kb/00 §6 sparkconfig 表告警 Webhook 行(gitignore 列 )、kb/90 §2.1 硬编码表 alerter 行 / §2.4 目录树 / §2.9 整节 4 处、kb/92 阶段 2 checklist 4 处(line 62 去掉"敏感文件"措辞、line 66 改为入库、line 78 钉钉条删除合并入 line 79、line 91 扩展名改)、记忆 project_templates_and_config 去掉"kb/92 一致性提醒"段(已消除)。未改动:2026-04-15 changelog line 139(历史快照保留)、2026-04-18 changelog line 153(历史快照保留)、workers.conf 扩展名 + kb/90 §2.1 里"ini 或 yaml 格式"未定的表述(不在本批范围,用户后续拍板)
2026-04-20 DS 残留清理 + workers / spark-defaults 扩展名收敛:(a) DS 残留:dw_base/ds/ 目录在 f20d9c3 就随老业务批被删,但前瞻 kb 未同步 —— 本次清 kb/00-项目架构.md:42 目录树 ds/ 行 + :122 Mermaid 节点 DS_API + :169 Mermaid 边 DS_API --> DS + kb/90-重构路线.md:70-72 目标态目录树 ds/ 子树 3 行。(b) conf/workers.confconf/workers.ini(kb/90 §2.1 硬编码表 + §2.4 目录树 + kb/92 checklist 2 处),并把 §2.1 里"ini 或 yaml 格式"的未决表述锁死为"ini 格式"—— 与本项目 Python 读配置统一走 configparser 的约定一致(见上一条 alerter 口径)。(c) conf/spark-defaults.yamlconf/spark-defaults.confSpark 原生 flat spark.x.y value 格式,非 ini):反转中途一度采纳的"全部配置 .ini 统一"结论,理由是该文件是 $SPARK_HOME/conf/spark-defaults.conf 的克隆(运维熟悉、与 spark-submit --properties-file 原生兼容、代码侧零映射转换、无 section 前缀/key 拼接 tax)。§2.3 草案块从 [executor]/[driver]/[sql]/[default] section + configparser + spark.{section}.{key} 拼接的写法,整段改写为 flat key-value;_load_default_config() 从 configparser 改为 10 行手写解析器。同步点:kb/90 §2.1 硬编码表 + §2.3 整节(草案 + 代码要点 + 两个落地坑 4 处引用)+ §2.4 目录树、kb/00 §6 配置分类表 + §6.2 三级覆盖图 + §6.2 说明段(启动加载方式从 "configparser" 改为 "Spark 原生 key value")、kb/92 checklist 2 处、记忆 project_templates_and_config 扩展名约定段追加 spark-defaults.conf 例外说明。未改动:2026-04-15 changelog line 134(conf/spark-defaults.yaml 历史快照保留)。路线外变更同步入册原则:DS 目录删除在 f20d9c3 未同步 kb 前瞻文档,属于此前"默默做完"漏记,本次补
2026-04-20 dw_base 占位模块骨架 + tests 骨架 + bin 收口(B4 提前 + C 起步):(a) 新建 5 个占位模块 dw_base/io/{db,file,hdfs}/ + dw_base/ops/ + dw_base/pm/ + dw_base/dq/ + dw_base/sync/,每个带 __init__.py + README.md(4 节:职责/接口/依赖/状态);实现留待后续阶段。(b) tests/{unit,integration}/ 骨架 + tests/README.md + .gitkeep;首批单测目标 tests/unit/udf/test_spark_common_udf.py(40 函数)。(c) bin/excel_to_hive.py 删除(一次性工具,有需求重做);publish.sh 从项目根 git mvbin/publish.sh(publish 是 DS 调度入口 = 和 bin 同类)。代码侧单次 commit 6936460。(d) 文档侧同步:kb/30-开发规范.md §4.5 占位模块规范(4 节标准 + "空 init.py 无 README → 删"铁律);kb/90-重构路线.md 按聚簇 + DAG 重组(新增 §〇 全景与 DAG、§2.10 common/utils/io/ops 四模块律、§2.11 新占位 registry、§六.1 tests 骨架标注、§八 从 P0-P3 线性表替换为聚簇 A-F 推进视图;所有主章节加 [聚簇 X] 标签;§2.1 publish.sh 行改为 bin/publish.sh);本文档总览引入聚簇视图说明 + 阶段 1/2/4 状态改"推进中 / 部分提前完成"