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

配置项作用 #

indices.fielddata.cache.size 配置项控制用于缓存字段数据(fielddata)的 JVM 堆内存大小。字段数据缓存用于加速对文档字段的排序、聚合和分析操作。

配置项类型 #

该配置项为动态配置,可以在运行时通过索引设置 API 进行修改。

默认值 #

-1b(不限制)

是否必需 #

可选配置项(有默认值)

配置格式 #

# 索引级别配置
PUT /my_index/_settings
{
  "index.fielddata.cache.size": "512mb"
}

# 百分比格式(相对堆内存)
PUT /my_index/_settings
{
  "index.fielddata.cache.size": "20%"
}

字段数据缓存的作用 #

字段数据缓存存储以下数据以提高查询性能:

┌─────────────────────────────────────────────────────────┐
│              字段数据缓存 (Field Data Cache)              │
└─────────────────────────────────────────────────────────┘
                        │
        ┌───────────────┼───────────────┐
        │               │               │
    字符串字段       数值字段       日期字段
    (倒排索引)       (doc values)   (epoch_ms)
        │               │               │
        ▼               ▼               ▼
    加速排序、聚合、脚本访问

使用场景 #

需要字段数据缓存的查询:

  1. 排序操作
{
  "sort": [
    {"user_name": "asc"},
    {"created_date": "desc"}
  ]
}
  1. 聚合操作
{
  "aggs": {
    "avg_price": {
      "avg": {"field": "price"}
    }
  }
}
  1. 脚本访问
{
  "script_fields": {
    "discounted_price": {
      "script": "doc['price'].value * params.discount"
    }
  }
}

推荐设置建议 #

生产环境建议:根据数据量和内存配置

数据特点推荐配置说明
小数据集100-500MB足够覆盖常用字段
中等数据集512MB-2GB平衡性能和内存
大数据集2GB-10GB覆盖热点数据
海量数据集10GB+或不限制

百分比配置:

# 相对于堆内存的百分比
index.fielddata.cache.size: 20%

配置示例 #

特定索引配置:

# 为不同索引设置不同的缓存大小
PUT /logs-2024/_settings
{
  "index.fielddata.cache.size": "2gb"
}

PUT /products/_settings
{
  "index.fielddata.cache.size": "500mb"
}

集群默认配置:

# 在 easysearch.yml 中设置默认值
# 注意:索引级别配置会覆盖集群级别
index.fielddata.cache.size: 1gb

缓存效果 #

有缓存 vs 无缓存:

操作类型无缓存有缓存
排序需要读取每个文档直接从缓存读取
聚合逐文档加载批量加载字段数据
脚本查询实时解档预加载字段数据

内存估算 #

字段数据大小估算:

字段类型每个文档约占用
字符串字段10-100 字节
数值字段8-16 字节
日期字段8-16 字节

示例计算:

100万文档 × 每个字段平均 20 字节 = 20MB
1000万文档 × 每个字段平均 20 字节 = 200MB

查看当前使用情况 #

# 查看索引的 fielddata 缓存使用
GET /_cat/indices?v&h=index,fielddata.memory_size&h=fielddata.evictions&h=store.size

# 查看节点级别的 fielddata 统计
GET /_nodes/stats/indices?filter_path=**.fielddata

常见问题 #

问题 1:缓存未生效

可能原因:

  • 查询没有使用需要字段数据的操作
  • 缓存被驱逐(内存不足)
  • 字段未配置为 doc_values

解决方案:

// 确保字段启用了 doc_values
PUT /my_index/_mapping
{
  "properties": {
    "user_name": {
      "type": "keyword",
      "doc_values": true
    }
  }
}

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

解决方案:

# 减小缓存大小
PUT /my_index/_settings
{
  "index.fielddata.cache.size": "256mb"
}

# 或清除缓存
POST /my_index/_cache/clear

问题 3:缓存驱逐频繁

解决方案:

  1. 增加缓存大小
  2. 优化查询减少不同字段访问
  3. 增加 JVM 堆内存

与断路器的关系 #

字段数据缓存受断路器保护:

配置项默认值说明
indices.fielddata.cache.size-1 (无限制)缓存大小
indices.breaker.fielddata.limit40%断路器限制

当字段数据加载超过断路器限制时,请求会被拒绝。

缓存清理 #

缓存会被以下情况触发清理:

  1. 内存压力:JVM GC 时可能清理
  2. 索引关闭:索引关闭时缓存释放
  3. 手动清理:通过 API 清除
# 手动清除 fielddata 缓存
POST /my_index/_cache/clear

相关配置项 #

配置项作用默认值
indices.breaker.fielddata.limit断路器限制40%
indices.queries.cache.size查询缓存大小10%
indices.requests.cache.size请求缓存大小1%

性能优化建议 #

  1. 只缓存需要的字段

    "properties": {
      "user_name": {
        "type": "keyword",
        "doc_values": true  // 仅对需要排序/聚合的字段启用
      }
    }
    
  2. 合理设置缓存大小

    • 避免过小导致频繁驱逐
    • 避免过大占用过多内存
  3. 监控缓存命中率

    GET /_nodes/stats/indices?filter_path=**.fielddata
    

注意事项 #

  1. 动态更新:索引级别配置可在线修改
  2. 内存分配:缓存从 JVM 堆分配
  3. 断路器保护:受 fielddata 断路器限制
  4. 字段类型:仅对支持 doc_values 的字段有效
  5. 全局影响:此配置影响所有使用字段数据的操作