开放问答
指标去重粒度选 user_id 还是 device_id:同一个 UV 差 40%,批处理耗时差 3 倍怎么取舍
该问题的正文、回答与评论。
提问者 许亦舟-170 · 状态 open
指标口径去重粒度UVClickHouse数据指标
【背景】 做了 10 年算法,近两年重心在指标体系与数据管道。负责一条 B 端 SaaS 的核心指标大盘,约 25 个指标,日粒度计算,底层是 ClickHouse(批)+ Flink(实时流)+ T+1 离线批。
【现象】 最近重构「独立访客数(UV)」这个指标时撞上一个很扎心的问题:
- 按 user_id 去重(仅登录用户):UV ≈ 12,340
- 按 device_id 去重(含未登录访客):UV ≈ 17,280
- 按 session_id 去重(按会话):UV ≈ 23,150
三个口径差了将近 40%。业务方问「到底哪个数是对的」,产品团队坚持要 device_id("未登录也是用户"),数据团队倾向 user_id("口径稳定、可归因"),运营又要 session_id("更接近真实触达")。更麻烦的是,下游有 8 个看板、3 个周报、2 个对外 API 依赖这个指标,换口径等于全部要改。
【已尝试的排查与结果】
- 拉 6 个月历史数据对比:按 user_id 去重,UV 半年增长 22%;按 device_id 去重,增长 31%——同一个业务,两个口径给出完全不同的增长叙事,业务方没法用,周会上吵了两次。
- 性能实测:在 ClickHouse 上
uniqExact(user_id)耗时约 1.2s,uniqExact(device_id)耗时约 4.5s(device_id 基数约 50 万 vs user_id 约 8 万)。日粒度 25 个指标全量批处理,device_id 方案把总耗时从 15 分钟拉到 40 分钟,Flink 实时链路的 state 也膨胀了约 3 倍。 - 近似去重:试过
uniqCombined64,误差率在 ±3%~±7% 之间波动,财务口径明确不接受,产品口径勉强能接受但要求标注"近似值"。 - 双指标并行:临时方案是同时维护
uv_user和uv_device两个指标,但看板上的指标数从 25 涨到 30+,业务方开始问"到底看哪个",指标字典维护成本翻倍。
【期望得到的答案形态】
- 决策框架:你们团队在「去重粒度」上有没有一套可复用的判断标准?比如什么场景必须用 user_id、什么场景用 device_id、什么场景用 session_id?核心判据是什么(归因需求?业务定义?性能约束?)?
- 多口径共存管理:当同一个"UV"在不同下游(产品看板 / 财务报表 / 运营活动)确实需要不同去重粒度时,是建 N 个独立指标(
uv_user、uv_device、uv_session)还是建 1 个指标 + 口径参数?指标字典怎么组织才不膨胀? - 性能优化:在保持精确去重(不用近似)的前提下,有没有加速大基数去重的好方法?比如 ClickHouse 的分桶策略、预聚合表设计、或者换引擎(StarRocks / Doris)的实际对比数据?
- 口径切换流程:如果最终决定换口径(比如从 user_id 切到 device_id),有没有"双轨并行 → 灰度切换 → 旧口径归档"的落地经验?怎么通知下游、怎么验证新旧口径一致性、怎么设定切换窗口?
评论
暂无评论。