淘宝用户行为项目是我完成度最高的一条离线数仓练习。它的输入很朴素:一个很大的行为明细 CSV,字段只有 user_id,item_id,category_id,behavior_type,ts,必须先按天切开才进得了集群。目标不是做几个看板,而是把 CSV 文件稳定加工成可调度、可校验、可追溯、可展示的电商数据仓库。

主链路如下:

text
UserBehavior.csv
  -> 按天切分
  -> Hadoop Landing + manifest
  -> ODS Batch TEXT
  -> ODS Parquet Snappy
  -> DWD 明细宽表
  -> DWS 用户/商品/漏斗汇总
  -> ADS KPI/画像/归因/排行/异常
  -> MySQL taobao_ads
  -> Flask + ECharts / Grafana

01集群与调度

项目文档记录的实验环境由一组 Hadoop 节点和一个独立的数据服务节点组成:

节点角色
Hadoop01NameNode、ResourceManager、Hive、Spark Master/Worker、Zookeeper、Kafka、Flume
Hadoop02DataNode、NodeManager、Spark Worker
Hadoop03DataNode、NodeManager、Spark Worker
mainMySQL、Airflow、BI 数据服务

Airflow DAG tb_data_pipeline 每天凌晨定时执行,任务顺序是:

text
validate_and_load
  -> dwd_transform
  -> dws_transform
  -> ads_transform
  -> sqoop_export

早期也保留过 shell/crontab 形式,后面统一收敛到 Airflow,方便查看执行状态和失败重跑。

02Landing 与 ODS:先保证文件可信

本地大 CSV 先通过 split_by_day.py 按北京时间切成每日文件,再由 offline-etl.py 上传到 Hadoop Landing。上传时生成 manifest,记录文件大小、行数和 SHA256。

ODS 层分两步:

  1. tb_ods_batch.user_behavior_di:TEXTFILE 暂存,接收原始分区。
  2. tb.ods_user_behavior_di:Parquet Snappy 标准化 ODS,补充 source_file、etl_time 和 dt 分区。

同一份数据从 TEXTFILE 转成 Parquet Snappy 之后,占用的存储空间明显下降,下游扫描时要读的字节也随之变少。这个结果说明列式存储和压缩不是“优化项”,而是后续 DWD/DWS 能稳定跑的基础。

03DWD:把行为日志加工成可分析明细

DWD 表 tb.dwd_user_behavior_di 保持明细行粒度不变,但把原始的几个字段扩展成一张可以直接分析的宽表。

新增字段包括:

  1. 行为中文名:pv/cart/fav/buy 映射为浏览、加购、收藏、购买。
  2. 时间维度:event_time、event_hour、day_of_week、is_weekend。
  3. 会话字段:session_id、session_seq、session_dur_sec,按固定的静默间隔切 session。
  4. 行为序列:prev_behavior、next_behavior。
  5. 漏斗标记:funnel_step,把浏览、加购、收藏、购买映射成递增的台阶。
  6. 质量字段:quality_flag。
  7. 溯源字段:source_file、etl_time。

DWD 的价值不是“多加字段”,而是把原始日志变成后续可复用的公共事实表。比如漏斗、归因、用户画像和异常监控都不需要重新解析时间戳或行为序列。

04DWS:按主题沉淀公共指标

DWS 层做轻度汇总,避免每张 ADS 报表重复扫 DWD。

表粒度说明
dws_user_daily用户 × 天pv/cart/fav/buy、会话数、活跃小时、购买商品/类目数
dws_item_daily商品 × 天商品行为计数、购买用户数、cart/fav/pv 到 buy 转化率
dws_funnel_daily天 × 步骤漏斗步骤用户数、相邻转化率、总体转化率
dws_etl_monitor步骤执行记录行数、耗时、状态和错误信息

当前资源有限,所以没有做小时级 DWS、Cube 预聚合和复杂留存表。这个取舍是有意的:在数据量不小、内存很紧的小集群里,先保证每日批处理稳定和幂等,比堆企业级名词更重要。

05ADS、BI 与数据治理

ADS 层面向应用和展示:

表用途
ads_kpi_dashboardDAU、转化率、复购率、Top 类目等管理看板指标
ads_user_feature_wide短窗与长窗行为特征、偏好类目、活跃时段、RFM 分层
ads_attribution_path会话级行为路径与转化归因
ads_item_top每日热销商品榜
ads_anomaly_daily移动均值、z-score、环比变化和告警

Hive ADS 通过 Sqoop 导出到 MySQL taobao_ads,Flask + ECharts 提供接口和前端页面。接口覆盖 KPI、趋势、漏斗、用户分层、小时分布、Top 商品、行为路径和异常监控。

治理侧补了几块:

  1. 数据地图:meta_catalog、meta_columns、meta_lineage,支持表搜索、表详情和血缘查询。
  2. 全链路可视化:把采集、ODS、DWD、DWS、ADS、MySQL、Flask 按链路阶段拆开。
  3. 质量规则:支持 row_count、null_rate、custom_sql 检查,记录规则和执行结果。

06当前验证边界

这条链路主要验证离线日批的分层、调度、导出与展示闭环,不把它包装成实时数仓或生产级高并发系统。性能压测、小时级汇总、告警通知和长期稳定性仍是后续要补的实验,而不是当前项目已经完成的承诺。

07工程复盘

这个项目的核心收获是:离线数仓不是写几段 SQL,而是让每个环节都能被验证。

我认为最能体现工程能力的点是这几条:

  1. Landing manifest 用 SHA256 和行数校验避免坏文件进入 ODS。
  2. ODS 从 TEXTFILE 转成 Parquet Snappy,存储与扫描成本一起降下来。
  3. DWD 保持明细粒度不变,同时补齐会话、漏斗、行为序列和质量字段。
  4. Airflow 串起加载、DWD、DWS、ADS、导出,形成可调度闭环。

后续如果升级,我会优先做小时级 DWS、告警通知、数据地图自动化血缘和更完整的留存/复购指标,而不是简单增加页面数量。