在海量日志(Logs)和指标(Metrics)场景下,随着时间推移,详细数据的存储成本会呈线性甚至指数级增长。然而,业务对于历史数据的查询需求往往不再需要精确到“毫秒级”的明细,而是关注“小时级”或“天级”的趋势统计。
INFINI Easysearch 内置的 Rollup(数据汇总)功能,通过将细粒度的历史数据定期“上卷”为粗粒度的统计摘要,能够将存储成本降低 90% 以上,同时保持秒级的查询响应速度。
本文将依据 Easysearch 的特性,详细解读如何配置、管理和使用 Rollup 功能。
1. Easysearch Rollup 的核心优势 #
与开源 Elasticsearch 的 Rollup 相比,Easysearch 做了大量企业级增强:
- 自动索引滚动 (Auto Rollover):无需额外部署 ILM(索引生命周期管理)策略,Rollup 产生的目标索引会自动根据文档数滚动,极大简化运维。
- 查询零代码修改:不需要使用特殊的
_rollup_searchAPI。直接使用标准的_searchAPI 即可查询汇总数据,系统会自动重写查询逻辑。 - 支持热更新 (Hot Update):运行中的任务发现粒度不合适?可以直接修改
page_size或interval,无需删除重建,任务会自动重启并应用新配置。 - 极致性能优化:提供“字段缩写”和“写入优化”选项,进一步降低内存占用并提升写入吞吐。
2. 环境准备与全局配置 #
在使用 Rollup 之前,需要确保集群配置已启用相关功能。
2.1 启用 Rollup 搜索 #
从 Easysearch v1.10.0 开始,默认可能未开启 Rollup 搜索功能,需手动启用:
PUT /_cluster/settings
{
"transient": {
"rollup.search.enabled": true
}
}
2.2 性能与流控配置(建议配置) #
为了防止大规模历史数据汇总查询通过占用过多资源影响实时业务,建议配置并发限制和时间边界:
PUT /_cluster/settings
{
"transient": {
"rollup.search.max_count": 2,
"rollup.hours_before": 24
}
}
3. 创建 Rollup 任务 (核心实战) #
Easysearch 的 Rollup 任务配置采用了扁平化的参数结构,支持对特定字段进行精细化统计。
3.1 场景示例 #
假设我们有一个监控索引 .infini_metrics,需要将分钟级数据聚合成小时级数据,保留机器 IP 和数据中心字段,并计算 CPU 和内存的统计值。
3.2 创建/替换任务 API #
PUT _rollup/jobs/node_stats_rollup
{
"rollup": {
"source_index": ".infini_metrics",
"target_index": "rollup_metrics_{{ctx.source_index}}",
"cron": "0 0 * * * ?",
"interval": "1h",
"timestamp": "timestamp",
"page_size": 1000,
"identity": [
"metadata.labels.ip",
"metadata.labels.datacenter"
],
"attributes": [
"metadata.category"
],
"stats": [
{
"max": {}
},
{
"min": {}
},
{
"value_count": {}
}
],
"metrics": [
"payload.cpu.usage",
"payload.mem.usage"
],
"special_metrics": [
{
"source_field": "payload.latency_ms",
"metrics": [
{
"avg": {}
},
{
"percentiles": {}
}
]
}
],
"write_optimization": true,
"field_abbr": true,
"is_continue": true
}
}
3.3 关键参数解析 #
identity: 相当于 SQL 中的GROUP BY字段。注意:不要放入高基数字段(如 UUID),否则会导致压缩率大幅下降。field_abbr: Easysearch 独有功能。开启后,底层存储会使用缩短的字段名,对于层级很深的 JSON 结构(如payload.elasticsearch.node_stats...),能节省大量内存和存储。write_optimization: 开启后,Rollup 写入时不检查 ID 冲突(直接生成新 ID),写入性能提升显著。
4. 任务运维与管理 #
4.1 启动与停止 #
任务创建后默认处于停止状态,需手动启动。Easysearch 支持通配符批量操作,这在管理数十个任务时非常有用。
# 启动所有 rollup 开头的任务
POST _rollup/jobs/rollup*/_start
# 停止特定任务
POST _rollup/jobs/node_stats_rollup/_stop
4.2 动态热更新 (Hot Update) #
这是 Easysearch 的一大亮点。在 v1.13.0 及以上版本,你可以动态调整运行参数,无需删除任务。
POST _rollup/jobs/node_stats_rollup
{
"page_size": 200, // 降低批处理大小以减轻负载
"interval": "30m" // 调整聚合粒度
}
执行逻辑:系统会自动停止任务 -> 更新参数 -> 重启任务 -> 自动记录断点位置。
4.3 查看任务详情与 Explain #
排查任务进度或错误信息:
GET _rollup/jobs/node_stats_rollup/_explain
响应中包含 documents_processed(已处理文档数)和 rollups_indexed(生成的汇总文档数),两者的比例即为压缩比。
5. 搜索汇总数据 #
Easysearch 的设计哲学是“对用户透明”。你不需要修改业务代码,也无需使用复杂的专用 API。
5.1 标准搜索 #
直接对目标索引(例如 rollup_metrics_*)使用标准的 _search API。
GET rollup_metrics_*/_search
{
"size": 0,
"aggs": {
"hourly_trend": {
"date_histogram": {
"field": "timestamp",
"fixed_interval": "1h"
},
"aggs": {
"avg_cpu": {
"avg": {
"field": "payload.cpu.usage"
}
},
"p99_latency": {
"percentiles": {
"field": "payload.latency_ms"
}
}
}
}
}
}
5.2 内部机制 #
当 Easysearch 接收到对 Rollup 索引的搜索请求时:
- 自动重写:引擎会自动识别 Rollup 索引,将
avg聚合重写为基于预计算的sum/count的逻辑。 - 约束检查:如果你请求了任务配置中未定义的聚合(例如对
metrics中没写的字段求和),查询会返回空或报错。
5.3 注意事项 #
- 不能混合搜索:原则上,不能在同一个
_search请求中同时包含“原始明细索引”和“汇总索引”,建议在业务层分路由处理。 - Filter 聚合:支持使用 Filter Aggregation 来替代 Query 阶段的过滤,某些场景下性能更优。
6. 最佳实践总结 #
- 生命周期配合:
- 原始数据:使用 ILM 保留 7 天,之后删除。
- Rollup 数据:配置 Rollup Job 实时运行,生成的数据保留 1 年。
- 结果:既能查最近 7 天的详细日志,又能查 1 年的历史趋势,且存储成本极低。
- 利用
target_index动态命名:
- 配置
target_index:rollup_{{ctx.source_index}},可以实现源索引和目标索引的一一对应(或模式对应),方便管理。
- 开启
field_abbr:
- 对于 Metricbeat 或复杂的 JSON 日志,字段名往往很长。开启此选项是性价比极高的优化手段。
通过合理使用 Easysearch Rollup,企业可以在不增加硬件投入的情况下,将监控数据的保留周期从“周”提升到“年”,真正实现数据的长期价值挖掘。





