适用版本: 7.1-8.9
1. 错误异常的基本描述 #
Search for expired snapshots failed 出现在 Elasticsearch 机器学习作业的 model snapshot 保留流程中。这里的 snapshot 不是仓库备份快照,而是 ML job 训练过程中保存的模型快照。源码显示,在为某个 job 搜索哪些 model snapshot 已经过期、可以进入后续删除阶段时,一旦查询或筛选逻辑失败,就会抛出这条异常。
它意味着“过期判定阶段”出了问题,后面的删除动作通常还没有真正开始。
常见现象 #
- ML job 的 model snapshot retention 没有按预期清理旧快照。
- 日志中出现
Search for expired snapshots failed,并伴随具体jobId。 - 老旧 model snapshot 持续积累,
.ml-state*或相关元数据负担增加。 - 后续删除过期快照的动作没有被触发,因为候选列表都没拿到。
典型报错与异常栈 #
ElasticsearchException: [job-1] Search for expired snapshots failed
2. 为什么会发生这个错误 #
在 ML job 清理旧 model snapshot 时,Elasticsearch 需要先查询该 job 的历史 snapshot,并依据保留规则判断哪些已经过期。只要这个查询、排序、过滤或回调链路失败,就会出现该异常。
常见原因通常包括:
.ml-config、.ml-state*或相关系统索引不可用,导致无法读取 model snapshot 元数据。- job 元数据异常,快照列表里存在损坏或不完整记录。
- 主节点或执行线程在 retention 回调中出错,导致过期搜索阶段中断。
- 集群处于升级、索引恢复或系统索引受限状态,ML 元数据读取失败。
3. 如何排查和解决这个异常和解决这个异常 #
建议按“先确认 ML 系统索引和 job 元数据是否可读,再判断是单 job 还是全局 retention 出错”的顺序处理:
- 从日志里取出失败的
jobId,确认问题是否只集中在个别 job。 - 检查 ML 相关系统索引与 job 配置是否健康可读。
- 查看是否刚发生版本升级、系统索引迁移或 ML 节点切换。
- 如果是单 job 问题,重点排查该 job 的 model snapshot 元数据是否有脏记录。
相关 Elasticsearch API #
GET /_ml/anomaly_detectors/{job_id}/model_snapshots:查看指定 job 的 model snapshot 列表。GET /_cluster/health:确认系统索引与集群整体状态。GET /_cat/indices/.ml*?v:检查 ML 系统索引是否可用。
排查时需要注意的问题 #
- 这里的 snapshot 不是仓库备份快照,不应按 repository/snapshot API 思路排查。
- 如果过期搜索失败,后续“删除快照失败”往往只是连锁表现,根因仍在前面的查询阶段。
- 不要忽略单个 job 的元数据损坏,它经常只影响一个 job,而不是所有 ML 任务。
4. 如何解决这个错误 #
常用修复思路 #
- 先恢复 ML 系统索引和 job 元数据的可读性,再重新触发保留流程。
- 对异常 job 单独检查 model snapshot 列表,必要时逐个确认快照元数据完整性。
- 在升级或维护窗口后核查 ML retention 是否恢复正常,避免旧快照长期堆积。
- 如果问题只在单 job 复现,优先围绕该 job 的模型快照历史做修复,而不是全局调大清理频率。
借助 INFINI 产品提升排障效率 #
- INFINI Console 适合统一查看 ML 作业状态、系统索引健康和 retention 异常日志。
- INFINI Gateway 可帮助审计是否有外部自动化在同一时间对 ML job 做高频操作。
5. 小结 #
Search for expired snapshots failed 的重点是 ML model snapshot 的“过期筛选阶段”失败了。排查时应优先回到 job 元数据和 ML 系统索引,而不是误判成普通仓库快照清理异常。
相关错误 #
- 指定 Job 搜索过期快照失败:同一问题的 job 级明细版本
- 指定 Job 删除快照失败:过期搜索成功后进入删除阶段的相邻异常
- 模型快照删除失败:按 model snapshot 对象执行删除时的相邻异常
- 删除快照失败:普通 repository snapshot 删除失败是另一条不同快照体系的相邻异常
附:日志上下文 #
@Override
public void onFailure(Exception e) {
listener.onFailure(new ElasticsearchException("[{}] Search for expired snapshots failed", e, job.getId()));
}





