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

配置项作用 #

indices.requests.cache 配置项控制请求缓存(Request Cache)的 JVM 堆内存大小。请求缓存用于缓存分片级别的查询请求结果(主要是 count 请求),提高重复查询的性能。

配置项类型 #

该配置项为静态配置,需要在启动时设置,修改后需要重启节点才能生效。

默认值 #

1%(JVM 堆内存的 1%)

是否必需 #

可选配置项(有默认值)

配置格式 #

# 百分比格式(默认)
indices.requests.cache.size: 1%

# 字节格式
indices.requests.cache.size: 100mb

# 混合格式
indices.requests.cache.size: 2%

配置项列表 #

配置项默认值说明
indices.requests.cache.size1%缓存大小
indices.requests.cache.expire0(不过期)缓存过期时间
index.requests.cache.enabletrue索引级别是否启用

工作原理 #

请求缓存在分片级别缓存查询结果:

┌─────────────────────────────────────────────────────────┐
│                   搜索请求                                │
│   GET /my_index/_search?request_cache=true               │
└─────────────────────────────────────────────────────────┘
                        │
                        ▼
            ┌───────────┴───────────┐
            │                       │
      缓存命中(同一Reader)     缓存未命中
      (索引未变更)             (首次查询或索引已变更)
            │                       │
            ▼                       ▼
    直接返回缓存结果          执行查询并缓存结果
      (毫秒级响应)

缓存 Key 组成:

CacheKey = IndexReader.CacheKey + CacheEntity + QueryBytes

使用场景 #

适用的查询类型:

  1. Count 请求(主要应用场景)
GET /my_index/_count?request_cache=true
{
  "query": {
    "term": { "status": "active" }
  }
}
  1. 可缓存的聚合查询
GET /my_index/_search?request_cache=true
{
  "size": 0,
  "aggs": {
    "by_status": {
      "terms": { "field": "status" }
    }
  }
}

使用示例 #

# 默认配置
indices.requests.cache.size: 1%

# 增加缓存大小
indices.requests.cache.size: 5%

# 设置字节大小
indices.requests.cache.size: 500mb

# 设置缓存过期时间
indices.requests.cache.expire: 10m

# 禁用缓存
indices.requests.cache.size: 0b

索引级别配置 #

# 启用索引的请求缓存(默认)
PUT /my_index/_settings
{
  "index.requests.cache.enable": true
}

# 禁用索引的请求缓存
PUT /my_index/_settings
{
  "index.requests.cache.enable": false
}

推荐设置建议 #

生产环境建议:根据查询模式和数据特点设置

场景推荐配置说明
默认1%基础缓存
大量 count 查询2-5%提高 count 性能
高频聚合3-10%缓存聚合结果
实时数据0-1%数据频繁变更,缓存失效快
静态数据5-10%数据变更少,缓存命中率高

缓存效果 #

命中率影响:

命中率性能提升内存使用适用场景
> 70%显著提升较高静态数据分析
40-70%明显提升适中周期性报表
20-40%轻微提升较低一般查询
< 20%几乎无效浪费不建议启用

查询请求级别控制 #

# 启用请求缓存
GET /my_index/_count?request_cache=true
{
  "query": {
    "term": { "status": "active" }
  }
}

# 禁用请求缓存
GET /my_index/_count?request_cache=false
{
  "query": {
    "term": { "status": "active" }
  }
}

查看缓存状态 #

# 查看请求缓存统计
GET /_nodes/stats/indices/request_cache?pretty

# 查看特定索引的缓存
GET /my_index/_cache/stats?pretty

# 查看缓存详细信息
GET /_cat/nodes?v&h=name,ip,*request_cache*

输出字段说明:

字段说明
hit_count缓存命中次数
miss_count缓存未命中次数
eviction_count缓存驱逐次数
memory_size_in_bytes缓存占用内存
hit_rate缓存命中率

缓存失效条件 #

请求缓存会在以下情况失效:

  1. 索引刷新(Refresh)

    • 默认每次 refresh 后缓存失效
    • 索引版本号变化
  2. 段合并(Merge)

    • 段合并后产生新 Reader
    • 旧 Reader 关联的缓存失效
  3. 索引更新

    • 文档被增删改后
    • 相关查询缓存失效
  4. 手动清理

    • 通过 API 清除缓存

缓存清理 #

# 清理特定索引的请求缓存
POST /my_index/_cache/clear?request_cache=true

# 清理所有索引的请求缓存
POST /_cache/clear?request_cache=true

# 清理所有类型的缓存
POST /_cache/clear

常见问题 #

问题 1:缓存未生效

可能原因:

  1. 索引级别未启用请求缓存
  2. 查询参数未设置 request_cache=true
  3. 索引频繁刷新导致缓存失效
  4. 查询使用了 now() 等随机函数

解决方案:

  1. 确认索引启用缓存
PUT /my_index/_settings
{
  "index.requests.cache.enable": true
}
  1. 使用确定性查询
// 避免 now()
{
  "query": {
    "range": {
      "timestamp": {
        "gte": "2024-01-01",
        "lte": "2024-01-31"
      }
    }
  }
}

问题 2:缓存占用内存过多

解决方案:

# 减小缓存大小
indices.requests.cache.size: 1%

# 或设置过期时间
indices.requests.cache.expire: 5m

问题 3:缓存命中率低

可能原因:

  • 数据频繁变更
  • 每次查询都不同
  • 索引频繁刷新

解决方案:

  1. 增加刷新间隔
index.refresh_interval: 30s
  1. 优化查询模式
// 使用固定的查询条件
{
  "query": {
    "bool": {
      "filter": [
        { "term": { "category": "electronics" } }
      ]
    }
  }
}

性能优化建议 #

1. 合理设置缓存大小

# 计算公式
缓存大小 = (单次查询结果大小 × 预期缓存数量) / JVM 堆内存

# 示例:单次结果 100KB,预期缓存 1000 个
# 100KB × 1000 = 100MB
# JVM 堆 8GB,建议设置 1-2%
indices.requests.cache.size: 2%

2. 配合索引刷新间隔

# 较长的刷新间隔可以提高缓存命中率
index.refresh_interval: 30s
indices.requests.cache.size: 3%

3. 使用过期时间

# 设置缓存过期时间,避免占用过多内存
indices.requests.cache.expire: 10m

监控建议 #

# 持续监控缓存命中率
GET /_nodes/stats/indices/request_cache?pretty

# 计算命中率
命中率 = hit_count / (hit_count + miss_count) × 100%

健康阈值:

指标健康警告严重
hit_rate> 50%20-50%< 20%
memory_size_in_bytes稳定持续增长接近限制
eviction_count0 或低中等高频

与查询缓存的区别 #

特性请求缓存 (Request Cache)查询缓存 (Query Cache)
缓存级别分片级别段级别
默认大小1%10%
主要用途count 请求查询结果
失效条件RefreshSegment 变更
配置项indices.requests.cache.sizeindices.queries.cache.size

相关配置项 #

配置项作用默认值
indices.queries.cache.size查询缓存大小10%
indices.fielddata.cache.size字段数据缓存大小-1 (无限制)
index.requests.cache.enable索引级别启用true
index.refresh_interval刷新间隔1s

注意事项 #

  1. 静态配置:修改缓存大小需要重启节点
  2. 内存占用:缓存占用 JVM 堆内存
  3. NRT 一致性:缓存与 NRT(Near Real Time)语义保持一致
  4. 命中率监控:建议定期监控缓存命中率
  5. 索引刷新:刷新会导致缓存失效,需合理设置刷新间隔