索引监控

Elasticsearch 索引监控:全方位追踪索引状态与性能

索引是 Elasticsearch 存储和查询数据的核心单元,其健康状态和性能直接影响整个集群的可用性。Elasticsearch 提供了一系列 API 用于监控索引的统计信息、分片状态、恢复进度等关键指标,帮助开发者和运维人员及时发现并解决问题。

索引统计信息(_stats

_stats API 提供索引的详细统计数据,涵盖文档数量、存储大小、索引 / 查询性能、缓存使用等维度,是监控索引整体状态的核心工具。

基本用法

  • 查看所有索引的统计信息:

    GET _stats  // 返回集群中所有索引的统计数据
  • 查看指定索引的统计信息:

    GET my_index/_stats  // 仅返回my_index的统计数据
  • 过滤统计维度(如仅查看存储和事务日志):

    GET my_index/_stats/store,translog  // 仅返回存储和事务日志信息

核心统计指标

(1)文档与存储信息(docs + store
{
  "primaries": {
    "docs": {
      "count": 10000,    // 文档总数
      "deleted": 500     // 标记删除的文档数(未实际删除,等待合并)
    },
    "store": {
      "size_in_bytes": 52428800  // 索引占用磁盘空间(50MB)
    }
  }
}
  • 关注点count 异常波动可能暗示批量写入或删除操作;size_in_bytes 增长过快需检查是否有大字段或冗余数据。
(2)索引操作统计(indexing
{
  "primaries": {
    "indexing": {
      "index_total": 5000,       // 累计索引操作次数
      "index_time_in_millis": 2000,  // 索引操作总耗时(毫秒)
      "index_current": 0,        // 当前正在执行的索引操作数
      "index_failed": 10         // 失败的索引操作数
    }
  }
}
  • 关注点index_failed 不为 0 可能是字段映射错误或数据格式问题;index_current 持续过高可能是写入压力过大。
(3)查询与搜索统计(search
{
  "primaries": {
    "search": {
      "query_total": 1000,       // 累计查询次数
      "query_time_in_millis": 500,   // 查询总耗时(毫秒)
      "fetch_total": 800,        // 累计获取文档次数
      "open_contexts": 5         // 当前打开的搜索上下文数(如滚动查询)
    }
  }
}
  • 关注点query_time_in_millis 平均值过高可能是查询语句未优化;open_contexts 过高可能是滚动查询未及时关闭。
(4)缓存使用(query_cache + fielddata
{
  "primaries": {
    "query_cache": {
      "memory_size_in_bytes": 1048576,  // 查询缓存占用内存(1MB)
      "hit_count": 300,                 // 缓存命中次数
      "miss_count": 100                 // 缓存未命中次数
    },
    "fielddata": {
      "memory_size_in_bytes": 2097152,  // fielddata缓存占用内存(2MB)
      "evictions": 50                   // 缓存驱逐次数(内存不足时)
    }
  }
}
  • 关注点evictions 频繁可能是 fielddata 缓存设置过小,需调整 indices.fielddata.cache.sizehit_count/miss_count 比例低说明缓存利用率低。
(5)事务日志(translog
{
  "primaries": {
    "translog": {
      "size_in_bytes": 1048576,    // 事务日志大小(1MB)
      "uncommitted_operations": 0  // 未提交到磁盘的操作数
    }
  }
}
  • 关注点size_in_bytes 过大可能导致刷新(flush)时 IO 压力激增,可调整 index.translog.flush_threshold_size

索引分片信息(_segments

_segments API 提供索引底层 Lucene 分段(Segment)的详细信息,包括分段数量、内存占用、文档数等,用于分析索引合并(Merge)和优化状态。

基本用法

  • 查看指定索引的分片信息:

    GET my_index/_segments  // 返回my_index的分段信息
  • 查看所有索引的分片信息:

    GET _segments  // 返回所有索引的分段信息

核心指标解析

{
  "indices": {
    "my_index": {
      "shards": {
        "0": [  // 分片ID
          {
            "routing": {
              "state": "STARTED",  // 分片状态(STARTED/INITIALIZING/UNASSIGNED)
              "primary": true     // 是否为主分片
            },
            "segments": {
              "_0": {  // 分段名称
                "docs": {
                  "count": 5000,   // 分段包含的文档数
                  "deleted": 100   // 分段中标记删除的文档数
                },
                "memory_in_bytes": 1048576,  // 分段占用内存(1MB)
                "size_in_bytes": 5242880     // 分段占用磁盘空间(5MB)
              }
            },
            "num_search_segments": 1  // 可搜索的分段数量
          }
        ]
      }
    }
  }
}
  • 关注点:
    • 过多小分段(num_search_segments 过大)会降低查询性能,需触发合并(force_merge)。
    • 分段 deleted 比例过高(如 >30%)说明删除操作频繁,可通过合并释放空间。

索引恢复信息(_recovery

_recovery API 用于监控索引分片的恢复进度(如节点重启后的数据同步、副本分片创建等),帮助评估恢复耗时和状态。

基本用法

  • 查看指定索引的恢复信息:

    GET my_index/_recovery  // 返回my_index的恢复信息
  • 查看所有索引的恢复信息:

    GET _recovery  // 返回所有索引的恢复信息

核心指标解析

{
  "my_index": {
    "shards": [
      {
        "id": 0,  // 分片ID
        "type": "PEER",  // 恢复类型(PEER:从副本恢复;SNAPSHOT:从快照恢复)
        "stage": "DONE",  // 恢复阶段(INITIALIZING/INDEX/TRANSLOG/DONE)
        "primary": false, // 是否为副本分片
        "start_time_in_millis": 1690000000000,
        "stop_time_in_millis": 1690000010000,
        "total_time_in_millis": 10000,  // 恢复总耗时(10秒)
        "index": {  // 索引文件恢复统计
          "size": {
            "total_in_bytes": 10485760,  // 总大小(10MB)
            "recovered_in_bytes": 10485760,  // 已恢复大小
            "percent": "100.0%"
          }
        },
        "translog": {  // 事务日志恢复统计
          "recovered": 100,  // 已恢复的事务日志操作数
          "total": 100,
          "percent": "100.0%"
        }
      }
    ]
  }
}
  • 关注点:
    • stage 长时间停留在 INDEXTRANSLOG 可能是网络缓慢或数据量过大。
    • total_time_in_millis 过长需检查 indices.recovery.max_bytes_per_sec(默认 40MB/s)是否限制了恢复速度。

索引分片存储信息(_shard_stores

_shard_stores API 用于查看索引分片的存储位置(节点信息),帮助确认分片是否正常分布在预期节点上,尤其适用于多节点集群。

基本用法

  • 查看指定索引的分片存储信息:

    GET my_index/_shard_stores  // 返回my_index各分片的存储节点

核心指标解析

{
  "indices": {
    "my_index": {
      "shards": {
        "0": {  // 分片ID
          "stores": [
            {
              "node_id": "node-1",  // 存储该分片的节点ID
              "name": "node-1",     // 节点名称
              "transport_address": "192.168.1.101:9300",  // 节点地址
              "allocation": "primary"  // 角色(primary/replica)
            },
            {
              "node_id": "node-2",
              "name": "node-2",
              "transport_address": "192.168.1.102:9300",
              "allocation": "replica"
            }
          ]
        }
      }
    }
  }
}
  • 关注点:
    • 主分片和副本分片是否分布在不同节点(避免单点故障)。
    • stores 数组为空,说明分片未分配(UNASSIGNED),需检查节点资源或集群配置。

监控最佳实践

  1. 定期巡检:结合 _stats_segments 定期检查索引状态,重点关注文档数、存储大小、查询耗时等指标的异常变化。

  2. 告警配置:对关键指标设置阈值告警(如 indexing.index_failed > 0search.query_time_in_millis 均值过高)。

  3. 分片优化:当_segments显示过多小分段时,执行force_merge合并分段(仅在只读索引或低峰期操作):

    POST my_index/_forcemerge?max_num_segments=1  // 合并为1个分段
  4. 恢复调优:节点故障恢复时,通过调整indices.recovery.max_bytes_per_sec加速恢复(需权衡集群负载):

    PUT _cluster/settings
    {
      "transient": { "indices.recovery.max_bytes_per_sec": "100mb" }
    }