配置项作用 #
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)
│ │ │
▼ ▼ ▼
加速排序、聚合、脚本访问
使用场景 #
需要字段数据缓存的查询:
- 排序操作
{
"sort": [
{"user_name": "asc"},
{"created_date": "desc"}
]
}
- 聚合操作
{
"aggs": {
"avg_price": {
"avg": {"field": "price"}
}
}
}
- 脚本访问
{
"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:缓存驱逐频繁
解决方案:
- 增加缓存大小
- 优化查询减少不同字段访问
- 增加 JVM 堆内存
与断路器的关系 #
字段数据缓存受断路器保护:
| 配置项 | 默认值 | 说明 |
|---|---|---|
indices.fielddata.cache.size | -1 (无限制) | 缓存大小 |
indices.breaker.fielddata.limit | 40% | 断路器限制 |
当字段数据加载超过断路器限制时,请求会被拒绝。
缓存清理 #
缓存会被以下情况触发清理:
- 内存压力:JVM GC 时可能清理
- 索引关闭:索引关闭时缓存释放
- 手动清理:通过 API 清除
# 手动清除 fielddata 缓存
POST /my_index/_cache/clear
相关配置项 #
| 配置项 | 作用 | 默认值 |
|---|---|---|
indices.breaker.fielddata.limit | 断路器限制 | 40% |
indices.queries.cache.size | 查询缓存大小 | 10% |
indices.requests.cache.size | 请求缓存大小 | 1% |
性能优化建议 #
只缓存需要的字段
"properties": { "user_name": { "type": "keyword", "doc_values": true // 仅对需要排序/聚合的字段启用 } }合理设置缓存大小
- 避免过小导致频繁驱逐
- 避免过大占用过多内存
监控缓存命中率
GET /_nodes/stats/indices?filter_path=**.fielddata
注意事项 #
- 动态更新:索引级别配置可在线修改
- 内存分配:缓存从 JVM 堆分配
- 断路器保护:受 fielddata 断路器限制
- 字段类型:仅对支持 doc_values 的字段有效
- 全局影响:此配置影响所有使用字段数据的操作





