ES Rollup 预聚合:报表从 3 秒到 200ms
招聘平台每天产生海量的行为日志:谁搜了什么职位、看了哪份简历、投递了几次。这些数据要喂给运营看板和转化漏斗分析,但量级上来之后,传统聚合方式撑不住了。
一、问题:明细数据太重
早期方案是把行为日志直接灌 ES,跑聚合:
- 数据量:单日行为日志 3000 万+ 条,保留 180 天 ≈ 5 亿+ 条
- 查询:漏斗分析按「投递 → 简历被查看 → 约面 → 入职」多级 join 聚合
- 现状:报表查询 3~5 秒,数据保留 180 天存储成本飙升,集群查询一多就排队
问题的本质是:明细数据只需要保留一小段热窗口,历史数据做报表时只关心聚合结果,不关心每一条明细。
二、Rollup 预聚合:把历史数据"降采样"
Elasticsearch 的 Rollup 能力本质是:按预定义的维度组合和粒度,把明细数据预先聚合成聚合桶,查询直接命中桶而不是扫明细。
具体做法
- 热窗口只留明细:行为日志明细索引只保留最近 7 天,配合 ILM 生命周期自动删除
- 每日滚动索引:明细按天建索引
behavior-2021-03-18,写满自动 rollover - Rollup 任务定义:指定聚合维度(职位 ID、城市、渠道、行为类型)+ 粒度(1 分钟)+ 指标(count、sum 时长)
- 历史数据落桶:超过 7 天的明细被 Rollup Job 消费成聚合桶,原始明细归档冷存储
查询层无感
Rollup 和明细共用同一个索引别名,_search 时带上 "typed_keys" 或直接对别名查询,ES 自动路由:新数据查明细,历史数据查聚合桶。报表 SQL 不需要改。
|
|
三、效果
| 指标 | 优化前 | 优化后 |
|---|---|---|
| 报表查询耗时 | 3~5 秒 | < 200ms(提速 80%+) |
| 明细存储保留 | 180 天全量 | 7 天明细 + 聚合桶 |
| 存储成本 | 100% | 降低 70%+ |
| 集群查询排队 | 高峰排队明显 | 明细索引瘦身后明显缓解 |
四、踩过的坑
- 聚合粒度不能乱设:1 分钟粒度对「近 7 天」够用,但运营要按秒看就查不到——明确「历史报表只关心分钟级以上」这个口径再上 Rollup,否则需求会打回来
- Rollup 任务消费有延迟:明细转桶是异步 cron,报表偶尔读到「昨天的数据还差几分钟」——加了个补偿查询:近 1 天数据直接查明细兜底
- 别名别乱用:Rollup 索引和明细索引共用别名后,写操作要小心——只对明细索引写,别对着别名写
- 维度要提前想全:Rollup 是预聚合,漏了的维度查不了。上线前和运营拉一遍「未来可能要的维度清单」,宁多勿少(多一个维度多一份存储,但少一个维度少一种分析能力)
总结
Rollup 的核心不是技术,是数据分层:热数据留明细,冷数据留聚合。预算好「报表精度」和「存储成本」的边界,Rollup 就是那把把报表从秒级拉到百毫秒级的钥匙。
如果你也在被历史数据报表拖垮,先别加机器,先算算:报表真的需要明细吗?