题目重点:用设备序列与事件时间处理重复迟到,将持久原始层、流式聚合和离线重算衔接,明确实时数据的暂定性。
题意与假设
这道练习题保留了面经中值得训练的核心约束,并将需要澄清的条件单独列出。现场拿到变体时,先和面试官确认这些条件。
- 训练假设百万设备每分钟一个1KB事件,具体上报频率/大小需现场核对;不继承其他公司规模。
- 事件含device_id、boot_id、sequence、event_time、schema_version;设备重启序列可归零,用boot身份避免误去重。
- 实时指标允许短暂修正,最终分析可重算;若必须严格一次计费,则需更强端到端幂等合同。
解题路线
- 训练吞吐约1.67万事件/秒、载荷约16.7MB/秒,每日原始约1.44TB,不含副本与协议。另估设备断线后补传峰值、保留时长和索引费用,不能只给平稳平均。
- 接入网关鉴权、限流、schema验证,持久日志后ACK;设备至少一次重试按设备/boot/sequence去重。原始事件保存到按时间/设备分区的对象存储,保留用于核对与重放。
- 流处理按event_time聚合,水位与allowed lateness定义何时窗口暂定/最终。新旧schema经版本适配;迟到事件更新受影响窗口或进入更正流,而不是静默丢弃。
- 实时服务用物化视图响应,批量任务读同一原始事实层重算,记录代码/输入版本与截止时间。发布离线结果用manifest或原子版本切换,避免半份新表与旧实时数据混合。
- 重放用独立任务身份与输出版本,去重状态、窗口与sink写入需协调。宣称exactly once必须说明故障重启时checkpoint与sink提交关系,单有队列并不足够。
- 监控采样覆盖、新鲜度、重复、schema拒绝、迟到与设备离线。坏设备隔离、租户限额及补传节流保护实时链路;查询返回as_of与数据可信度,避免误导dashboard。
手动走一遍
训练例设备重启前bootA/seq7与重启后bootB/seq7为不同事件;bootA/seq7重试才是重复。昨日事件今天补传,实时视图标迟到修正,夜间批任务按原始层重算昨日窗口并发布新版本,不能将其计入今日流量指标。
规模与取舍
稳定写入与流式聚合近似每事件O(1),去重状态按时间保留与设备频率增长;批任务O(读取字节),查询受分区剪枝与聚合粒度影响。运营成本需计原始层和实时索引两份用途。
易错点与追问
容易失分的边界
- 使用device_id+sequence但忘设备重启。
- 事件时间和接收时间混用。
- 批任务结果覆盖流式表,造成重复计数/版本混读。
- 没有原始事实层,修复代码后无法重算。
继续深挖
- 离线一年设备补传要不要接受?
- schema新字段导致旧设备事件全被拒怎样回滚?
- 实时与批量结果不同,用什么证据对账?
- 租户删除数据时原始、索引与重放怎样协调?
