13-埋点同步-设计.md 6.5 KB

埋点数据同步方案(设计文档)

受众:产品 / CTO / 协作方。本文档说明埋点数据从 ES 进入数仓的整体方案、合规取舍、协作约束。 实现细节见 kb/14-埋点同步-开发.md

1. 背景与需求

  • 数据源:埋点系统后端 = Elasticsearch(生产单环境,无 dev / test)
  • 量级:约 1.4M event / 天;事件类型 50+ 长尾
  • 存量形式:按天 NDJSON.gz 文件(ES _search 导出,每行一个 ES hit 文档)
  • 增量形式:实时写入 ES traces-{YYYY-MM-DD} 滚动索引
  • 业务目的:用户行为分析(留存、漏斗、转化、活跃度等)

2. 合规约束

  • 公司原则:敏感数据不出业务库 / 不入数仓
  • 涉敏举例
    • 下单事件:收货地址、收件人姓名、收件人手机号
    • 退款事件:银行卡号
    • 其他事件按业务实际声明
  • 合规优先级:合规 > 数据完整性 > 开发便利
  • 合规对"入仓"的定义:物理存储层面的存在,不是逻辑层面的可访问性。一旦敏感字段落地到 HDFS / Hive 表,即使下游不查询也算违规

3. 整体方案

                 ┌────────────────┐
                 │  埋点 ES (prod) │
                 └────┬───────────┘
                      │
         ┌────────────┴─────────────┐
         │                          │
    [增量路径]                  [历史路径]
   每日 ES → Hive          一次性 .json.gz 文件
   ES Storage Handler            按天解压解析
   映射表 SELECT                 Python 脚本
         │                          │
         └────────────┬─────────────┘
                      │
              【入仓阶段脱敏】
              (按事件类型应用规则)
                      │
                      ▼
           ┌──────────────────┐
           │   raw 层(数仓)  │
           └──────────────────┘

两条路径最终落到同一张 raw 表,schema 一致;脱敏规则共用同一份配置。

4. 设计取舍:raw 层默认范式破例

数仓默认 raw 层走 schema-on-read landing 范式(数据原样落、ods 阶段才做类型转换 / 脏数据识别,详见 kb/20-数仓分层与建模.md §8.1)。本场景主动破例

§8.1 理由 是否适用 说明
1. 隔离源端类型变化 埋点 schema 长尾,新事件 / 新字段频繁,本就要求协作通知
2. 同步阶段不可失败 部分适用,需对解析失败做容错处理
3. 保留原始精度与原文 合规要求就是要丢字段,与"保原文"目标冲突
4. 脏数据可观测 事件本身可观测,脱敏后字段不可回溯(合规接受这代价)
5. schema-on-read 范式契合 合规要求物理拦截敏感字段,不能等 ods 读取阶段才处理

3 条不适用 ≥ §8.1 阈值,破例成立。

破例代价(明示)

  • 入仓阶段需做 JSON 解析 + 字段脱敏 + 配置化逻辑
  • 埋点上下游 schema 变更需协作通知(违反"隔离源端"原则)
  • ods 失去"raw 一定有原始数据可回溯"的兜底保障

5. 脱敏策略

5.1 三种脱敏动作

动作 含义 适用
drop 字段直接删除,不入 raw 高敏字段(地址、手机号、卡号等)
mask 字段保留但用脱敏函数处理 中敏字段(脱敏后的姓名、订单号末四位等)
reject 整事件不入 raw 极敏感事件(如有)

脱敏函数复用现有的 5 种:md5 / month_trunc / mask_middle / keep_first_n / keep_last_n(实现见开发文档)。

5.2 配置驱动

所有脱敏规则集中在一份配置文件(conf/tracking-mask.ini),格式与加载方式见开发文档。

5.3 兜底策略:选项 3 不加固

  • 未在配置中的事件 / 字段:默认允许,全部原样入 raw
  • 配置中显式声明 drop / mask 的字段:按规则处理
  • 风险:新含敏事件没及时进配置 → 原文入仓 → 违规
  • 风险缓解:靠协作流程(§6)+ 审计机制(§6.2)

候选选项(已否决)

  • 选项 1(事件级白名单):任何新事件不在 conf 都不入仓——卡业务上线节奏,否决
  • 选项 2(字段级白名单仅对已声明事件):含敏事件首次进 conf 时所有字段必须登记,后续上游加字段自动 drop——多一道保险但仍有"全新含敏事件没及时进 conf"风险,与选项 3 漏的根本场景相同,多余的复杂度不抵收益,否决

6. 协作流程

6.1 三种新事件场景

场景 处理
新事件 + 无敏感字段 默认入仓,无需通知
新事件 + 有敏感字段 强制走流程:埋点开发方 PR 注明 → 数仓更新配置
已有事件加敏感字段 同上

6.2 审计机制

每日 ods 跑前对比当日 ES 出现的 event_name 集合 vs 配置已知集合,新增事件列表推 alerter(企微)。

数仓收到通知后人工判断是否含敏:

  • 含敏 → 立即更新 conf
  • 不含敏 → 无需操作(继续兜底)

6.3 应急响应

发现敏感字段误入仓时:

  1. 立即更新 conf 加 drop / mask 规则
  2. 历史数据:对受影响 dt 分区跑回填,覆盖原数据
  3. 复盘:分析为何协作流程失守

7. 风险与决策点

7.1 已识别风险

  • R1 协作流程失守:新含敏事件没及时进 conf → 违规
    • 缓解:审计机制(§6.2)+ 应急响应流程(§6.3)
  • R2 ES Storage Handler 故障:增量路径中断
    • 缓解:DS 调度告警 + 重跑(INSERT OVERWRITE 幂等)
  • R3 历史数据脱敏不彻底:早期入仓的非脱敏数据残留
    • 缓解:现 testbed 数据按本方案重跑(落地范围决策见 §7.2)

7.2 已锁定决策

  • 加固方案:选项 3 不加固
  • raw 表组织:单 wide schema 表(不按事件分多张)
  • 现 testbed 处置:暂不处理(drop 重做或换名共存留待后续单独评估)

8. 落地范围

本方案仅覆盖 raw 层入仓 + 脱敏。后续阶段(不在本方案):

  • ods 层 schema 设计(按事件分流解析 params_json)
  • dwd / dws / ads 层建模
  • 实时埋点路径(如需要)