es快速释放内存

ES索引占用内存原理

一、核心原理:ES索引必须占用的内存

ES索引至少需要占用以下内存(无法完全释放):

索引元数据:分片信息、映射、设置等(每个索引几KB到几MB);

字段数据(Field Data):聚合、排序时加载的字段值(可通过配置避免);

查询缓存:频繁查询的结果缓存(可清理但会自动重建);

分段内存:索引分段的倒排索引、词频统计等(必须加载)。

二、最小化内存占用的方法(从效果显著到辅助优化)

1.将索引设置为只读+关闭字段数据加载(最有效)

适用于备份索引、归档数据等几乎不查询的场景:

powershell 复制代码
curl -s -k -u elastic:Passw0rd -XPUT "http://es_node:9200/pds_msg_record_auto_backup/_settings" -H "Content-Type: application/json" -d '{
  "index.blocks.write": true,           #设置为只读
  "index.queries.cache.enabled": false,  #禁用查询缓存
  "index.fielddata.cache.size": "0",     #禁用字段数据缓存  选用
  "index.refresh_interval": "-1"         #关闭自动刷新(减少内存缓冲区) 选用
}'

2.使用最佳压缩策略+优化映射(减少内存中的数据量)

powershell 复制代码
# 创建索引时指定最佳压缩
curl -s -k -u elastic:Passw0rd -XPUT "http://es_node:9200/pds_msg_record_auto_backup" -H "Content-Type: application/json" -d '{
  "settings": {
    "index.codec": "best_compression",    #使用最高压缩比
    "number_of_replicas": 0,              #关闭副本(仅备份索引适用)
    "index.mapping.total_fields.limit": 1000  #限制字段数
  },
  "mappings": {
    "properties": {
      # 使用更节省内存的字段类型
      "user_id": { "type": "keyword" },
      "timestamp": { "type": "date" },
      "status": { "type": "integer" },     #用integer代替keyword
      "content": { 
        "type": "text",
        "index": false                     #不需要搜索的字段设置为不索引
      }
    }
  }
}'

3.强制段合并+刷新策略优化(减少分段内存)

powershell 复制代码
#合并为最少分段(每个分片1-2个)
curl -s -k -u elastic:Passw0rd -XPOST "http://es_node:9200/pds_msg_record_auto_backup/_forcemerge?max_num_segments=1"
#关闭实时刷新(仅对只读索引)
curl -s -k -u elastic:Passw0rd -XPUT "http://es_node:9200/pds_msg_record_auto_backup/_settings" -d '{
  "index.refresh_interval": "-1"
}'

4.使用冻结索引(Frozen Index)(ES 6.6+)

冻结索引将内存中的数据卸载到磁盘,查询时临时加载:

powershell 复制代码
#冻结索引(大幅减少内存占用,但查询变慢)
curl -s -k -u elastic:Passw0rd -XPOST "http://es_node:9200/pds_msg_record_auto_backup/_freeze"

#解冻索引(恢复正常查询性能)
curl -s -k -u elastic:Passw0rd -XPOST "http://es_node:9200/pds_msg_record_auto_backup/_unfreeze"

三、效果预期

只读+关闭缓存:内存占用减少50%-70%;

冻结索引:内存占用减少80%-90%(但查询延迟增加10-100倍);

快照备份+删除索引:内存占用减少100%(但需从快照恢复才能查询)。

四、验证缓存清理是否生效

1.查看索引缓存统计(精确验证)

powershell 复制代码
# 查看段内存使用
curl -s -k -u elastic:Passw0rd -XGET "http://es_node:9200/_cat/segments?v"
curl -s -k -u elastic:Passw0rd -XGET "http://es_node:9200/_cat/segments/pds_msg_record_auto_backup"
#清理前查看缓存统计
curl -s -k -u elastic:Passw0rd -XGET "http://es_node:9200/pds_msg_record_auto_backup/_stats/fielddata,query_cache,request_cache?pretty"
-- query_cache.memory_size_in_bytes: 0(查询缓存无内存占用)
-- fielddata.memory_size_in_bytes: 0(字段数据缓存无内存占用)
-- request_cache.memory_size_in_bytes: 0(请求缓存无内存占用)
-- 缓存已被清空:query_cache.cache_size: 0 说明缓存中无任何有效数据,之前的 167 条缓存记录已被驱逐(evictions: 167)

#执行清理
释放指定索引的全部缓存
curl -s -k -u elastic:Passw0rd -XPOST http://es_node:9200/pds_msg_record_auto_backup/_cache/clear
释放指定索引的特定类型缓存:若只需清理某一类缓存(如字段数据、查询缓存),可通过参数指定。
清理字段数据缓存
curl -s -k -u elastic:Passw0rd -XPOST http://es_node:9200/pds_msg_record_auto_backup/_cache/clear?fielddata=true 
清理查询缓存
curl -s -k -u elastic:Passw0rd -XPOST http://es_node:9200/pds_msg_record_auto_backup/_cache/clear?query=true
清理分片请求缓存
curl -s -k -u elastic:Passw0rd -XPOST http://es_node:9200/pds_msg_record_auto_backup/_cache/clear?request=true
释放指定索引的特定字段缓存:若要精准清理个别字段的缓存,用fields参数指定字段名,该命令仅清理指定字段相关缓存。
curl -s -k -u elastic:Passw0rd -XPOST http://es_node:9200/pds_msg_record_auto_backup/_cache/clear??fields=userName,age
#清理后立即查看(可能还有残留)
curl -s -k -u elastic:Passw0rd -XGET "http://es_node:9200/pds_msg_record_auto_backup/_stats/fielddata,query_cache,request_cache?pretty"
#等待几分钟后再查看(GC后)
sleep 300
curl -s -k -u elastic:Passw0rd -XGET "http://es_node:9200/pds_msg_record_auto_backup/_stats/fielddata,query_cache,request_cache?pretty"
  1. 查看节点级缓存使用
powershell 复制代码
# 查看所有缓存使用情况
curl -s -k -u elastic:Passw0rd -XGET "http://es_node:9200/_nodes/stats/indices/fielddata,query_cache,request_cache?pretty"
  1. 手动触发 GC(立即释放内存)
powershell 复制代码
# 清理缓存后手动触发垃圾回收
curl -s -k -u elastic:Passw0rd -XPOST "http://es_node:9200/_nodes/stats/indices/fielddata,query_cache,request_cache?pretty"
# 然后查看内存变化
curl -s -k -u elastic:Passw0rd http://es_node:9200/_cat/nodes?v&h=name,heap.current,heap.percent

内存分析


powershell 复制代码
curl -s -k -u elastic:Passw0rd -XGET "http://es_node:9200/group_tag_all_boci/_stats/fielddata,query_cache,request_cache?pretty"

{"_shards" : {"total" : 2,"successful" : 2,"failed" : 0},"_all" : {"primaries" : {"query_cache" : {"memory_size_in_bytes" : 34706566,"total_count" : 1229311,"hit_count" : 47719,"miss_count" : 1181592,"cache_size" : 637,"cache_count" : 1880,"evictions" : 1243},"fielddata" : {"memory_size_in_bytes" : 0,"evictions" : 0},"request_cache" : {"memory_size_in_bytes" : 4273432,"evictions" : 0,"hit_count" : 568,"miss_count" : 654}},"total" : {"query_cache" : {"memory_size_in_bytes" : 62748530,"total_count" : 2183787,"hit_count" : 71593,"miss_count" : 2112194,"cache_size" : 1241,"cache_count" : 2572,"evictions" : 1331},"fielddata" : {"memory_size_in_bytes" : 0,"evictions" : 0},"request_cache" : {"memory_size_in_bytes" : 7913128,"evictions" : 0,"hit_count" : 1141,"miss_count" : 1252}}},"indices" : {"group_tag_all_boci" : {"uuid" : "37zIJkIfSLO4s0IeI6sW2Q","primaries" : {"query_cache" : {"memory_size_in_bytes" : 34706566,"total_count" : 1229311,"hit_count" : 47719,"miss_count" : 1181592,"cache_size" : 637,"cache_count" : 1880,"evictions" : 1243},"fielddata" : {"memory_size_in_bytes" : 0,"evictions" : 0},"request_cache" : {"memory_size_in_bytes" : 4273432,"evictions" : 0,"hit_count" : 568,"miss_count" : 654}},"total" : {"query_cache" : {"memory_size_in_bytes" : 62748530,"total_count" : 2183787,"hit_count" : 71593,"miss_count" : 2112194,"cache_size" : 1241,"cache_count" : 2572,"evictions" : 1331},"fielddata" : {"memory_size_in_bytes" : 0,"evictions" : 0},"request_cache" : {"memory_size_in_bytes" : 7913128,"evictions" : 0,"hit_count" : 1141,"miss_count" : 1252}}}}}

核心结论:group_tag_all_boci 索引的缓存占用明显(查询缓存~60MB、请求缓存~7.6MB),且缓存命中率极低(仅 3.2%),缓存不仅没起到优化作用,还占用内存,建议清理缓存并调整配置避免无效缓存堆积。

一、关键缓存状态解读(问题核心)

  1. 缓存占用情况
    查询缓存:总占用~62.7MB(memory_size_in_bytes: 62748530),缓存条目 1241 条;
    请求缓存:总占用~7.9MB(memory_size_in_bytes: 7913128);
    字段数据缓存:0 占用(正常,无频繁聚合 / 排序操作)。
  2. 核心问题:缓存命中率极低
    查询缓存命中率 = 命中数 ÷ 总查询数 = 71593 ÷ 2183787 ≈ 3.2%;
    意味着 96.8% 的查询都没命中缓存,缓存不仅没提升性能,还额外占用内存、增加缓存管理开销(如驱逐旧缓存)。

二、优化方案(先清理再禁用无效缓存)

  1. 立即清理现有缓存(释放~70MB 内存)
powershell 复制代码
# 清理 group_tag_all_boci 索引的所有缓存
curl -s -k -u elastic:Passw0rd -XPOST "http://es_node:9200/group_tag_all_boci/_cache/clear"

# 验证清理结果(缓存内存应变为 0)
curl -s -k -u elastic:Passw0rd -XGET "http://es_node:9200/group_tag_all_boci/_stats/fielddata,query_cache,request_cache?pretty"
  1. 长期优化:调整缓存配置(若后续命中率提升)
    若未来查询模式变化(如频繁重复查询),可重新启用并限制缓存大小:
powershell 复制代码
curl -s -k -u elastic:Passw0rd -XPUT "http://es_node:9200/group_tag_all_boci/_settings" -d '{
  "index.queries.cache.enabled": true,
  "index.queries.cache.size": "50mb",  # 限制查询缓存最大 50MB
  "index.request_cache.size": "10mb"   # 限制请求缓存最大 10MB
}'

三、为什么会出现低命中率?(避免重复踩坑)

查询模式多样:业务查询多为非重复查询(如不同用户、不同条件的实时查询),缓存无法复用;

数据更新频繁:Hive每天全量更新索引,旧缓存会因数据变化失效,新缓存又难以命中;

缓存配置不合理:默认缓存大小可能过大,导致无效缓存堆积,占用内存。


总结


核心结论:要让备份索引不占用文件系统缓存、不主动加载分段到内存,最彻底的方案是"冻结索引+调整系统缓存策略"------冻结索引让ES主动卸载内存数据,系统层面限制缓存占用,双管齐下解决问题。

一、核心实现方案(从ES配置到系统优化)

1.冻结备份索引(ES层面主动卸载内存)

冻结是ES专为归档/备份索引设计的功能,能完全满足"不占用文件系统缓存、不主动加载分段"的需求:

powershell 复制代码
# 冻结两个备份索引(立即卸载核心数据和分段,仅保留少量元数据)
curl -s -k -u elastic:Passw0rd -XPOST "http://es_node:9200/pds_msg_record_auto_backup/_freeze"
curl -s -k -u elastic:Passw0rd -XPOST "http://es_node:9200/pds_decision_instance_auto_backup/_freeze"

冻结后效果:

ES会将索引的分段数据从文件系统缓存中驱逐,不再主动加载;

内存占用(RAM)会在1-5分钟内明显下降(节点 es_node的RAM使用率预计从92%降至75%以下);

索引变为只读,无法写入/更新,完美适配备份索引的用途。

  1. 调整ES索引配置(防止缓存再生)

冻结后补充配置,彻底杜绝备份索引占用缓存:

powershell 复制代码
curl -s -k -u elastic:Passw0rd -XPUT "http://es_node:9200/pds_msg_record_auto_backup,pds_decision_instance_auto_backup/_settings" -H "Content-Type: application/json" -d '{
  "index.queries.cache.enabled": false,  # 禁用查询缓存
  "index.fielddata.cache.size": "0",     # 禁用字段数据缓存
  "index.refresh_interval": "-1",        # 关闭自动刷新(不产生新分段缓存)
  "index.blocks.write": true             # 强制只读,避免任何写入操作触发缓存
}'
  1. 系统层面限制文件系统缓存(可选,进阶优化)
    如果冻结后RAM使用率仍偏高,可在ES节点服务器上调整内核参数,限制文件系统缓存对备份索引的占用(需root权限):
powershell 复制代码
# 1. 临时生效(重启后失效,适合测试)
sysctl -w vm.drop_caches=3  #释放页缓存、目录项和inode缓存
sysctl -w vm.swappiness=10  #降低内存交换倾向,优先释放缓存而非交换
# 2. 永久生效(修改/etc/sysctl.conf,重启服务器生效)
echo "vm.drop_caches=3" >> /etc/sysctl.conf
echo "vm.swappiness=10" >> /etc/sysctl.conf
sysctl -p  #加载配置
注意:该操作会释放所有进程的文件系统缓存,执行时需避开业务高峰,仅建议在备份索引所在节点执行。

二、关键原理

1.冻结索引的核心作用

卸载分段数据:冻结后ES会主动将索引的倒排索引、文档数据从文件系统缓存和ES堆内存中移除,仅保留索引元数据(几KB);

禁止主动加载:查询时需手动解冻或临时加载,备份索引查询极少,几乎不会触发加载;

不影响数据安全:数据仍存储在磁盘,解冻后可正常使用。

2.其他方案

仅清理缓存:缓存会因后续查询/操作重新加载,无法根治;

关闭文件系统缓存:会影响业务索引的查询性能,得不偿失;

删除索引+快照备份:虽然完全释放内存,但查询需恢复快照,操作复杂,不适用于偶尔需要查询的备份场景。

三、验证效果(确保备份索引不占用内存)

powershell 复制代码
# 1.查看节点内存变化(冻结后1-5分钟执行)
curl -s -k -u elastic:Passw0rd http://es_node:9200/_cat/nodes?v&h=name,ram.percent,heap.percent

# 2.查看备份索引状态(确认已冻结)
curl -s -k -u elastic:Passw0rd -XGET "http://es_node:9200/_cat/indices/pds_msg_record_auto_backup?v&h=index,status,docs.count,store.size"

# 3.验证缓存占用(应为0)
curl -s -k -u elastic:Passw0rd -XGET "http://es_node:9200/pds_msg_record_auto_backup/_stats/fielddata,query_cache,request_cache?pretty"
备份索引的各类缓存占用为 0,分段未加载到内存。

索引启用


备份索引查询时,无需长期解冻,用"临时加载查询"或"按需短期解冻"即可------既不占用常驻内存,又能满足偶尔的查询需求,具体方法如下:

一、优先方案:临时加载查询(推荐,不解冻索引)

适合仅需单次查询、查询后无需保留加载状态的场景,查询完成后内存自动释放:

1.执行查询时添加 ignore_throttled=false 参数

冻结索引默认被"限流"(throttled),添加该参数可临时加载分段到内存,查询完成后ES会自动卸载:

powershell 复制代码
# 示例:查询备份索引中user_id=xxx的数据
curl -s -k -u elastic:Passw0rd -XGET "http://es_node:9200/pds_msg_record_auto_backup/_search?ignore_throttled=false" -H "Content-Type: application/json" -d '{
  "query": {
    "term": { "user_id": "target_user" }
  }
}'

特点:无需手动解冻,查询后内存自动释放,不影响索引冻结状态;

注意:首次查询可能因加载分段略慢(秒级到分钟级,取决于数据量),后续同分段查询会复用缓存(但关闭自动刷新,缓存不会长期保留)。

2.批量查询/复杂查询(如聚合、导出)

若需执行多轮查询或复杂统计,可临时开启索引的"自动加载",查询完成后立即关闭:

powershell 复制代码
# 1.临时允许自动加载(不解冻,仅开启加载权限)
curl -s -k -u elastic:Passw0rd -XPUT "http://es_node:9200/pds_msg_record_auto_backup/_settings" -d '{
  "index.search.throttled": false
}'

# 2. 执行多次查询/复杂查询(如导出数据、聚合统计)
curl -s -k -u elastic:Passw0rd -XGET "http://es_node:9200/pds_msg_record_auto_backup/_search" -d '{...}'  # 第1次查询
curl -s -k -u elastic:Passw0rd -XGET "http://es_node:9200/pds_msg_record_auto_backup/_search" -d '{...}'  # 第2次查询

# 3. 查询完成后,关闭自动加载(恢复限流)
curl -s -k -u elastic:Passw0rd -XPUT "http://es_node:9200/pds_msg_record_auto_backup/_settings" -d '{
  "index.search.throttled": true
}'
特点:多轮查询复用已加载的分段,查询速度更快;关闭后内存逐步释放,不占用常驻资源。

二、备选方案:短期解冻查询(适合高频临时查询)

若需在一段时间内(如1小时)多次查询,可短期解冻,查询完成后重新冻结:

1.解冻索引(恢复正常状态,加载分段到内存)

powershell 复制代码
curl -s -k -u elastic:Passw0rd -XPOST "http://es_node:9200/pds_msg_record_auto_backup/_unfreeze"

解冻后:索引恢复可写(但已设置 index.blocks.write: true,仍只读),分段加载到内存,查询速度与正常索引一致。

2.执行查询(无任何限制)

powershell 复制代码
#正常执行各类查询,无需额外参数
curl -s -k -u elastic:Passw0rd -XGET "http://es_node:9200/pds_msg_record_auto_backup/_search" -d '{...}'

3.查询完成后,重新冻结(释放内存)

powershell 复制代码
curl -s -k -u elastic:Passw0rd -XPOST "http://es_node:9200/pds_msg_record_auto_backup/_freeze"
重新冻结后:内存中的分段会被卸载,恢复"零常驻内存"状态。
相关推荐
q***76662 小时前
显卡(Graphics Processing Unit,GPU)架构详细解读
大数据·网络·架构
九河云2 小时前
不同级别华为云代理商的增值服务内容与质量差异分析
大数据·服务器·人工智能·科技·华为云
阿里云大数据AI技术2 小时前
【跨国数仓迁移最佳实践 12】阿里云 MaxCompute 实现 BigQuery 10 万条 SQL 智能转写迁移
大数据·sql
Elastic 中国社区官方博客3 小时前
Elasticsearch:Microsoft Azure AI Foundry Agent Service 中用于提供可靠信息和编排的上下文引擎
大数据·人工智能·elasticsearch·microsoft·搜索引擎·全文检索·azure
DolphinScheduler社区3 小时前
结项报告完整版 | 为 Apache DolphinScheduler 添加 gRPC 插件
大数据·开源·apache·海豚调度·大数据工作流调度
Faith_xzc3 小时前
Doris内存问题指南:监控、原理与高频OOM解决方案
大数据·性能优化·doris
学习吖4 小时前
vue中封装的函数常用方法(持续更新)
大数据·javascript·vue.js·ajax·前端框架
空空kkk4 小时前
SpringMVC框架——入门
java·spring
Saniffer_SH4 小时前
通过近期测试简单聊一下究竟是直接选择Nvidia Spark还是4090/5090 GPU自建环境
大数据·服务器·图像处理·人工智能·驱动开发·spark·硬件工程
雾山大叔4 小时前
Python学习 - 面向对象学习-文件分类小测试
java·前端·spring