适用版本: 7.11-8.9
1. 错误说明 #
failed to start rollup task 表示 Elasticsearch 在尝试启动 Rollup 任务时,内部的 indexer.start() 方法未能返回 IndexerState.STARTED 状态,导致任务启动流程被中断并抛出异常。
Rollup 是 Elasticsearch 提供的一种历史数据降采样机制,用于将高频细粒度数据按时间窗口聚合后写入目标索引,从而降低存储成本并提升历史数据查询效率。当 Rollup Job 被创建并提交后,Elasticsearch 会尝试启动一个异步 indexer 来执行滚动聚合任务;如果 indexer 无法正常进入 STARTED 状态,就会触发此异常。
常见现象 #
- 调用
_rollup/startAPI 后任务状态始终为stopped或aborting,无法进入started。 - 在 Elasticsearch 日志中可以看到
failed to start rollup task异常信息。 - 目标 rollup 索引中没有任何聚合数据写入,历史数据降采样流程完全中断。
- 如果任务反复尝试启动,可能会在日志中观察到大量失败重试记录,伴随节点资源消耗升高。
典型报错 #
ElasticsearchException: failed to start rollup task
at org.elasticsearch.xpack.rollup.RollupJobTask$1.onFailure(RollupJobTask.java:XX)
Caused by: java.lang.IllegalStateException: Indexer not in STARTED state
2. 原因分析 #
从源码层面看,Rollup 任务启动的核心逻辑如下:
if (indexer.start() == IndexerState.STARTED) {
indexer.maybeTriggerAsyncJob(Long.MAX_VALUE);
} else {
listener.onFailure(new ElasticsearchException("failed to start rollup task"));
}
当 indexer.start() 返回的状态不是 IndexerState.STARTED 时,就会触发此异常。常见根因包括:
- Rollup Job 配置非法:
source_index不存在或已被删除;cron表达式格式错误;groups或metrics中引用了不存在的字段或使用了不支持的聚合类型。 - 源索引状态异常:源索引处于
close状态、索引分片未分配完成、或索引存在index.read_only_allow_delete阻塞。 - 任务状态冲突:同名 Rollup Job 已在其他节点上运行,或之前的任务实例未正常清理,导致 indexer 无法获取执行权。
- 目标索引问题:目标 rollup 索引已存在但 mapping 与当前聚合配置不兼容,或目标索引所在节点磁盘空间不足。
- 节点资源不足:节点 JVM 堆内存压力大、线程池(
rollup线程池)已满,导致 indexer 无法被正常调度。 - 集群状态不稳定:在任务启动瞬间集群发生 master 漂移、节点加入/离开,导致任务上下文丢失。
3. 解决方案 #
步骤一:检查 Rollup Job 配置 #
使用以下 API 查看当前 job 的配置详情:
GET _rollup/job/<job_id>
重点检查以下字段:
source_index:确认索引存在且处于open状态。cron:确认表达式合法,可使用 cron 在线工具 验证。groups.date_histogram.field:确认时间字段在源索引中存在且类型为date。metrics:确认引用的字段类型和聚合函数匹配(如max/min仅适用于数值字段)。
步骤二:检查任务状态与节点日志 #
查看任务当前状态:
GET _rollup/job/<job_id>/_stats
同时检查 Elasticsearch 节点日志,搜索关键字:
grep -i "rollup\|failed to start" /var/log/elasticsearch/elasticsearch.log
步骤三:确认索引状态 #
检查源索引和目标索引的健康状态:
GET _cat/indices/<source_index>,<target_index>?v
GET _cluster/allocation/explain
如果源索引被关闭,需要先打开:
POST <source_index>/_open
步骤四:清理冲突状态后重启任务 #
如果任务状态异常,先停止任务:
POST _rollup/job/<job_id>/_stop
确认任务已停止后,再重新启动:
POST _rollup/job/<job_id>/_start
步骤五:检查节点资源 #
查看节点线程池状态,确认 rollup 线程池是否正常:
GET _cat/thread_pool/rollup?v
GET _nodes/stats/thread_pool
如果 JVM 堆压力过高,考虑扩容或优化查询负载后再启动任务。
4. 预防措施 #
- 配置校验前置:在创建 Rollup Job 前,使用
PUT _rollup/job/<job_id>的 dry-run 模式(或先在测试环境验证)确认配置合法。 - 源索引生命周期管理:为源索引设置合理的 ILM 策略,避免索引被意外关闭或删除;对历史数据使用
delete而非close操作。 - 资源监控告警:对 rollup 线程池队列长度、JVM 堆使用率、磁盘剩余空间设置告警阈值,在资源不足时提前介入。
- 任务状态巡检:定期通过
_rollup/job/_all/_stats检查所有 rollup 任务状态,及时发现stopped或aborting状态的异常任务。 - 版本兼容性注意:Rollup 功能在 Elasticsearch 7.x 中处于试用状态,8.x 中已标记为弃用(deprecated),建议在新版本中优先考虑 Data Streams 配合 downsampling 替代方案。
5. 相关错误 #
- failed-to-build-aggregation-aggregator-name-how-to-solve-this-elasticsearch-exception
- all-shards-failed-how-to-solve-this-elasticsearch-exception
- index-not-found-how-to-solve-this-elasticsearch-exception
附:日志上下文 #
以下为触发此异常的源码片段,便于结合完整异常栈定位问题:
// RollupJobTask.java
if (indexer.start() == IndexerState.STARTED) {
indexer.maybeTriggerAsyncJob(Long.MAX_VALUE);
} else {
listener.onFailure(new ElasticsearchException("failed to start rollup task"));
}





