4. 迁移前的架构评估:现有Batch系统的组件依赖、数据血缘与瓶颈分析

从 Batch 迁移到实时,第一步不是写代码,而是把现有 Batch 系统“解剖”清楚。很多团队跳过这一步直接改造,结果上线后数据对不上、链路断掉、性能还不如 Batch。本节聚焦三个核心评估维度:组件依赖(谁依赖谁)、数据血缘(数据从哪来到哪去)、瓶颈分析(哪里最慢、哪里最脆弱)。

4.1 组件依赖:理清系统“上下游”

Batch 系统通常由多个模块串联或并联组成,每个模块有明确的输入输出和调度顺序。迁移前必须画出完整的依赖图,否则实时改造时容易遗漏关键依赖。

关键动作: 收集所有 Batch 作业的调度配置、输入源、输出目标、中间表、触发条件,形成组件依赖矩阵。

4.1.1 典型 Batch 组件清单

组件类型 常见实现 依赖关系 迁移影响
数据采集 Sqoop / DataX / Flume 依赖上游 DB、日志源 需替换为 CDC 或消息队列
ETL 清洗 Hive / Spark SQL 依赖采集完成、依赖维表 需重构为流式 SQL 或 Flink
特征计算 Python / PySpark 依赖清洗后的宽表 需改为状态计算或窗口聚合
规则引擎 Drools / 自研规则 依赖特征表、依赖模型输出 需支持事件驱动触发
预警输出 MySQL / Redis / 消息推送 依赖规则判定结果 需保证低延迟写入

4.1.2 依赖关系可视化

下面这张 SVG 图展示了一个典型贷后 Batch 预警系统的组件依赖关系,箭头表示数据流向和调度顺序。

典型贷后 Batch 预警系统组件依赖图 数据源(DB/日志) 维表(客户/产品) 外部征信接口 数据采集(Sqoop) 维表同步(DataX) 接口拉取(Python) ETL 清洗 & 宽表构建(Hive/Spark) 特征计算(PySpark / 窗口聚合) 规则引擎(Drools / 自研)
评估要点: 每个组件是否有“硬依赖”(必须等前序完成才能启动)?是否有“软依赖”(可并行或异步)?实时迁移时,硬依赖组件需要优先改造为事件驱动。

4.2 数据血缘:追踪数据“前世今生”

数据血缘记录了数据从产生、加工、聚合到最终输出的完整链路。Batch 系统中,血缘通常隐藏在 SQL 脚本、调度日志和中间表里。迁移到实时后,血缘关系必须保持完整,否则排查问题时无从下手。

4.2.1 血缘分析的核心要素

  • 数据源:原始表、接口、日志文件,记录字段级来源。
  • 加工节点:每个 ETL 步骤、特征计算、规则判定,记录输入输出映射。
  • 中间存储:临时表、宽表、特征表,记录生命周期和保留策略。
  • 消费端:预警结果表、推送消息、下游系统,记录最终去向。

4.2.2 数据血缘示例(字段级)

血缘层级 节点名称 输入字段 输出字段 转换逻辑
L1 源 loan_order — order_id, user_id, amount, due_date 原始表
L2 清洗 etl_loan_clean order_id, amount, due_date clean_order_id, clean_amount, overdue_days 过滤异常、计算逾期天数
L3 特征 feat_user_risk clean_amount, overdue_days, user_id avg_overdue_30d, max_overdue, loan_count 窗口聚合、用户维度汇总
L4 规则 rule_trigger avg_overdue_30d, max_overdue alert_level, alert_reason 阈值判断、规则匹配
常见陷阱: Batch 系统中很多血缘关系是“隐式”的——比如某个字段在 SQL 里用 row_number() over (partition by ...) 生成,但文档没写。迁移前必须通过解析 SQL 或日志反推,否则实时流中会丢失关键字段。

4.3 瓶颈分析:找到“最慢的一环”

Batch 系统的瓶颈通常集中在三个地方:数据倾斜、资源争抢、调度等待。迁移到实时前,必须量化这些瓶颈,否则实时系统会继承甚至放大这些问题。

4.3.1 常见瓶颈类型与诊断方法

瓶颈类型 典型表现 诊断方法 实时迁移影响
数据倾斜 部分 Task 运行时间远超其他 查看 Spark/Hive 任务日志,对比各分区数据量 实时中需做 key 打散或状态分区优化
资源争抢 同一时间多个作业抢占 CPU/内存 YARN 资源监控、作业并发数统计 实时需预留独立资源池,避免 Batch 干扰
调度等待 作业排队时间 > 执行时间 查看调度系统(Azkaban/Airflow)DAG 等待时长 实时需去掉调度层,改为事件触发
IO 瓶颈 大量读写 HDFS/MySQL,磁盘吞吐打满 监控磁盘 IO、网络带宽、数据库连接池 实时需引入消息队列缓冲,减少直接 IO
中间表膨胀 临时表数据量巨大,占用大量存储 统计各中间表行数、存储大小 实时需改为状态存储(RocksDB/Redis)

4.3.2 瓶颈量化分析示例

以下是一个真实 Batch 系统的瓶颈分布(基于某消费金融公司贷后预警系统):

Batch 系统各阶段耗时占比(分钟) 数据采集 12min ETL 清洗 & 宽表 20min 特征计算(数据倾斜严重)28min 规则引擎 16min 输出 10min 瓶颈分析结论 • 特征计算占比最高(28min / 33%) • 根因:用户维度数据倾斜,部分 key 数据量 是平均值的 50 倍 • ETL 清洗次之(20min),因多表 join 无索引 • 调度等待未计入,实际排队平均 8min • 实时迁移优先级:特征计算 → ETL → 规则 → 采集 → 输出

4.4 评估输出:迁移就绪清单

完成组件依赖、数据血缘和瓶颈分析后,需要输出一份可执行的评估报告。以下清单可作为模板:

迁移就绪检查清单(示例)
  • ✅ 组件依赖图已绘制,识别出 3 个硬依赖节点(ETL → 特征 → 规则)
  • ✅ 数据血缘已追踪到字段级,发现 2 个隐式转换(row_number 和 lag 函数)
  • ✅ 瓶颈已量化:特征计算 28min(数据倾斜),ETL 20min(多表 join)
  • ✅ 已识别 4 个中间表可替换为状态存储(tmp_feature_*, tmp_rule_*)
  • ✅ 已确认调度等待平均 8min,实时方案可完全消除
  • ⚠️ 外部征信接口延迟不稳定(平均 2s,P99 8s),需设计超时重试机制
最佳实践: 评估阶段不要追求完美。先画出 80% 的依赖和血缘,剩下的 20% 在迁移过程中逐步补齐。关键是让团队对现有系统的“痛点”达成共识,避免实时改造时重复踩坑。