📣 极限科技诚招搜索运维工程师(Elasticsearch/Easysearch)- 全职/北京 👉 : 立即申请加入

适用版本: 8.1-8.9

1. 错误异常的基本描述 #

Could not perform time series aggregation 是 Elasticsearch 在执行时间序列索引(time series index)上的聚合查询时抛出的运行时异常。该异常通常发生在搜索阶段,由 AggregationExecutionException 包装抛出,表示当前聚合上下文无法在时间序列索引模式下正常执行。

常见现象 #

  • 查询请求返回 500400 状态码,异常信息包含 Could not perform time series aggregation
  • 错误通常发生在包含 time_series 聚合或针对 time_series 类型索引执行聚合时,尤其是涉及 compositehistogramdate_histogram 等聚合类型。
  • 如果错误频繁出现,往往说明聚合 DSL 与当前索引的 time series 配置存在结构性不兼容,而非偶发故障。
  • 在 Elasticsearch 日志中可以看到类似如下的异常栈:
org.elasticsearch.search.aggregations.AggregationExecutionException: Could not perform time series aggregation
    at org.elasticsearch.search.aggregations.bucket.timeseries.TimeSeriesAggregator.collect(TimeSeriesAggregator.java:XX)
    ...
Caused by: IOException: ...

2. 为什么会发生这个错误 #

时间序列索引是 Elasticsearch 8.x 引入的一种特殊索引模式,通过 index.mode: time_series 启用。它使用 synthetic _source 并对维度(dimension)和指标(metric)字段做了严格区分。当聚合执行时,底层 collector 需要与 time series 的存储结构对齐,若不满足约束就会抛出此异常。

常见原因包括:

  • 聚合类型不兼容:在 time series 索引上使用了 time series 聚合不支持的聚合类型,或将普通聚合嵌套在 time_series 聚合内部。
  • 维度字段缺失或类型不匹配:time series 聚合依赖 @timestamp 字段及已声明为 dimension: true 的字段,若这些字段不存在、类型不符,或 _source 配置不满足 synthetic source 要求,聚合无法执行。
  • 索引模式冲突:查询同时覆盖了 time series 索引和非 time series 索引,而聚合 DSL 只适用于 time series 模式,导致在普通索引分片上执行失败。
  • 内存或遍历限制:time series 聚合需要在内存中维护时间线状态,若时间线数量过多或分段过多,可能触发底层 IOException 或内存压力,进而抛出的包装异常。
  • 映射变更不兼容:在索引生命周期中修改了字段的 dimension/metric 角色,或重建索引时未保持相同的 time series 配置。

3. 如何排查这个异常 #

建议按以下顺序定位问题:

  1. 确认索引模式:检查目标索引是否开启了 index.mode: time_series,以及索引模板中是否正确配置了 time_series 相关设置。

    GET /your-index/_settings
    GET /your-index/_mapping
    
  2. 检查聚合 DSL:确认查询中是否使用了 time_series 聚合,以及嵌套聚合是否均为 time series 模式支持的类型。避免在 time_series 聚合内嵌套不支持的子聚合。

  3. 验证字段定义:确认 @timestamp 字段存在且类型为 datedate_nanos,维度字段已设置 dimension: true,且 _sourcemodesynthetic(或保持默认兼容配置)。

  4. 缩小复现范围:在测试环境使用最小聚合 DSL 复现问题,逐步添加聚合层级,定位触发异常的具体聚合类型或字段组合。

  5. 检查混合索引查询:若查询使用了通配符索引模式(如 logs-*),确认是否同时匹配了 time series 索引和非 time series 索引。可尝试将查询限定到单一 time series 索引验证。

4. 如何解决这个错误 #

修复方案 #

  • 调整聚合 DSL:确保 time_series 聚合作为顶层聚合使用,内部只嵌套 time series 模式支持的子聚合(如 maxminsum 等指标聚合)。避免在 time_series 聚合内使用 termsfilter 等普通聚合。

    {
      "aggs": {
        "time_series": {
          "time_series": {
            "key": {
              "field": "host.name"
            }
          },
          "aggs": {
            "avg_cpu": {
              "avg": {
                "field": "system.cpu.usage"
              }
            }
          }
        }
      }
    }
    
  • 修正字段映射:确保维度字段正确声明 dimension: true,指标字段使用合适的数值类型,且 @timestamp 字段存在且类型正确。

    {
      "properties": {
        "@timestamp": { "type": "date" },
        "host.name":  { "type": "keyword", "dimension": true },
        "system.cpu.usage": { "type": "double", "metric": true }
      }
    }
    
  • 隔离查询范围:若查询同时覆盖 time series 索引和非 time series 索引,使用索引模式或别名将查询限定到 time series 索引,或为不同索引类型分别构造聚合 DSL。

  • 重建索引:如果映射配置已无法兼容,考虑使用 Reindex API 将数据迁移到正确配置的新索引中,确保新索引模板的 time series 设置完整。

后续注意事项与推荐建议 #

  • 在索引模板中明确声明 index.mode: time_series 及相关字段角色,避免依赖动态映射产生不兼容的字段定义。
  • 对 time series 聚合查询建立独立的测试场景,在映射变更或模板更新时回归验证,防止生产环境突发异常。
  • 监控 time series 索引的分段数量和内存使用情况,避免因时间线膨胀导致聚合执行失败。

借助 INFINI 产品提升排障效率 #

  • INFINI Console 适合查看集群健康度、索引模式、映射配置、慢查询和聚合执行趋势,帮助快速判断异常是否与索引配置或查询 DSL 相关。
  • INFINI Gateway 适合部署在 Elasticsearch 前面做请求观测、DSL 审计和流量治理,在聚合异常出现时可以捕获完整请求与响应,辅助定位问题聚合。

5. 小结 #

Could not perform time series aggregation 并非运行时偶发故障,而是聚合 DSL 与 time series 索引约束不匹配的结构性问题。处理时优先检查 time_series 聚合的使用方式、维度字段定义和索引模式配置,将查询调整到与 time series 模式兼容的形态,即可从根本上解决该异常。

相关错误 #

附:日志上下文 #

    searcher.setMinimumScore(context.minimumScore());
    searcher.setProfiler(context);
    try {
        searcher.search(context.rewrittenQuery(), bucketCollector);
    } catch (IOException e) {
        throw new AggregationExecutionException("Could not perform time series aggregation", e);
    }
    collector = BucketCollector.NO_OP_COLLECTOR;
} else {
    collector = bucketCollector.asCollector();
}