题目重点:将多篇 metrics monitoring / event aggregation / behavior tracking 设计题合并,明确事件契约、富化版本、实时与仓库两条读路径。
题意与假设
这道练习题保留了面经中值得训练的核心约束,并将需要澄清的条件单独列出。现场拿到变体时,先和面试官确认这些条件。
- 核心实体是获同意的用户行为事件,不把它和主机 CPU/服务 uptime 指标混为同一数据产品;真实事件字段、隐私策略、QPS、保留期在题目未统一。
- 训练 API 为 `POST /v1/events` 批量接收 `{event_id,tenant_id,subject_id,event_type,event_time,properties,schema_version}`,返回 accepted/invalid;字段、去重 TTL、同意信号与最大批量需要产品和合规确认。
解题路线
- SDK 在移动/浏览器端做批量、压缩、有限离线队列与退避重试;事件有全局稳定 ID、时间与 schema 版本。对设备端无法可靠记录的时钟要保留 ingestion_time;同意状态、租户边界和敏感字段在入口验证。
- 入口服务认证/限流/校验后先写耐久事件日志,再异步分流;raw 事件进入可重放的廉价存储,避免实时聚合口径变化后无法重算。对重复 event_id 在限定窗口幂等处理,迟到事件按明确 watermark/修正策略。
- 富化从版本化维表补地理、产品或合规标签,记录维表版本和失败状态;geo lookup/外部依赖超时时可延后富化或隔离重试,不能阻断全部事件。对历史回补须说明按事件时刻的维表版本还是最新版本。
- 实时分支按 tenant、event_type、时间桶聚合,用低基数维度预计算 dashboard 读模型;distinct user 计数须另定精确/近似口径。复杂探索查询走列式/仓库表与异步 job ID,而非让用户在实时 API 上扫 raw 全量。
- 指标卡声明如‘日安装数’以哪个时区、去重键、测试设备过滤和迟到截止定义;监控摄入 lag、坏事件比率、富化失败、实时与回算差异。Data update/correction 通过原事件或修正事件重放相关窗口,不直接无审计覆盖聚合值。
手动走一遍
用户在离线手机上点击两次,SDK 缓存并批量发送;网络重试时事件 ID 不变。入口日志收一次事实,聚合层去重后计算当前小时点击数,富化层补产品/地区标签;若地区维表暂不可用,事件仍可落 raw、稍后回填看板。分析师做 90 天跨维查询走仓库异步任务。
规模与取舍
设每日 E 条事件、平均原始事件大小 B,raw 每日约 E×B 字节(另有索引/副本/压缩),实时聚合写入约按实际维度组合数增长;仪表盘读延迟可随预聚合固定为查少量桶,任意复杂 SQL 无法得到同样上界。题目无 E/B/维度基数,不能填机器数。
易错点与追问
容易失分的边界
- 只画一个 cron+SQL DB,却同时承诺低延迟实时看板和大范围 ad hoc 查询。
- 只存聚合,不存 raw,口径修正时无法回算。
- 把移动端请求数压到最小而不考虑积压/时效;或逐事件上报导致电量和网络开销。
- 富化覆盖原始事件,不留维表版本和失败原因。
- 把用户行为指标误说成系统可靠性指标。
继续深挖
- SDK 批量大小与实时性怎样权衡?
- 晚到 48 小时的事件如何修正看板?
- 用户撤回同意后的 raw 与聚合怎样处理?
- 为什么某个查询适合时间序列读模型,另一个适合列式仓库?
- 回填后怎样对账实时与离线结果?
