Elasticsearch线上问题之OOM

俗话说得好,人在河边走,哪有不湿鞋

咱们的Es宝贝被越来越多的人看到,难免也有些是非,今天咱们不惧绯闻,大胆的来说一说吧

1. OOM Killer 突然干掉 ES 进程

有没有这种经历:我大手一挥直接给了 32G 内存,这么富裕的仗,ES 应该很稳",结果半夜收到告警:节点离线,服务中断。( 虚拟场景,不要当真哦,还是要结合业务**)**

复制代码
# elasticsearch.yml
-Xms32g
-Xmx32g   # ← 危险!超过 32G左右(看版本) 指针压缩失效,建议30
  • 💥 现象:节点无故下线killed,也没有日志OOM,咱们上命令:dmesg -T | grep -i "killed process"

    [Thu Feb 6 03:14:22 2025] Out of memory: Kill process 12345 (java) score 899 or sacrifice child
    [Thu Feb 6 03:14:22 2025] Killed process 12345 (java), UID 1000, total-vm: 65000000kB, anon-rss: 31000000kB

    #JVM OOM:Java 抛异常,ES 进程还在(可重启)
    #Linux OOM Killer:直接 kill -9 进程,无日志、无预警、无商量!

  • ES 的内存 = JVM 堆 + 非堆(Off-Heap);或 fielddata/聚合吃光堆内存;

内存区域 用途 是否受 -Xmx 控制
JVM Heap fielddata、聚合、查询上下文 ✅ 是
Lucene Off-Heap 倒排索引(FST)、Doc Values、缓存 ❌ 否!由 OS Page Cache 管理
Netty Direct Memory 网络缓冲区(Bulk 请求) ❌ 否!默认无上限

所以,有点眉目了吧,你以为-Xmx32g,就是只用了32g?太单纯、后台的内幕你知道不?lucene会把倒排索引、docValues加载到PageCache (可能占20-50g),而且Netty缓冲区还要再吃个几G,(咱们Netty默默无闻就可以被无视嘛!第一个不答应)

总内存 = 32(堆) + 30G(非堆) = 62G > 机器 64G这无疑是老鼠和猫玩游戏------不要命了

所以咱们Liunx 看不下去了,触发OOM Killer ,优先把占用内存最大的进程ES给die了

复制代码
#JVM OOM:Java 抛异常,ES 进程还在(可重启)
#Linux OOM Killer:直接 kill -9 进程,无日志、无预警、无商量!

💡 更隐蔽的问题 :藏了一把大的!JVM 堆设太大(如 -Xmx64g),导致 指针压缩失效,内存翻倍

-Xmx 约32GB 时,JVM 指针压缩(Compressed Oops)失效 ,导致 实际堆内存膨胀 20%+(32G 堆 ≈ 38G 物理内存):每个对象引用从4字节膨胀成8字节,堆内存增加 gc压力山大

而且下面如果不注意也会很有隐患:自古大哥不是好当的,自己人可能就keng个够呛 🤣

1、容许text字段加载fielddate

复制代码
PUT /my_index/_mapping
{ "properties": { "content": { "type": "text", "fielddata": true } } }

这样导致什么呢?所有的唯一值加载到jvm堆 ,都想占据一席之地;再者说1亿条不同日志,堆不直接爆,天理难容!

2、不做熔断限制,这妹妹就有点糊涂了,明显涉世未深,这🉑️不能不调,原来的不老实呢

复制代码
# 默认熔断器只限制 70% 堆,但非堆内存不受控
indices.breaker.request.limit: 60%  # ← 很多人没调

正确姿势:💃💃💃 ✅ 必须配置,否则大聚合会吃光堆

复制代码
# elasticsearch.yml
indices.breaker.request.limit: 40%     # 单请求最多用 40% 堆
indices.breaker.fielddata.limit: 20%   # fielddata 最多 20%
network.breaker.inflight.requests.limit: 50%  # 网络缓冲
  • 🛠️ 解决
    • JVM 堆 ≤ 31GB(推荐 26--30GB)-Xms30g -Xmx30g 保证指针压缩生效,这么重要的好东西咱不用那是糊涂,可不能糊涂两次咯;30G 堆 ≈ 32G 物理内存
    • 留给Lucene至少50%的物理内存, 不能让大将军无处可去,那么多士兵无家可归!机器是64G,堆就要30G,剩下34G给OsPageCache(lucene用,当然别的也用,共享的)
    • 同时不要设swap(bootstrap.memory_lock: true )锁内存 防 swap!
    • 监控 一查看熔断器状态GET /_nodes/stats/breaker ;二查看fileddata使用情况GET /_stats/fielddata?fields=*,俗话说小心驶得万年船,多加注意
    • 健康dmesg或/var/log/messages中的killed process java,一双眼睛时刻盯着案发现场,当然也可以用filebeat+es自身做日志分析,一直盯着也难受是不是
    • 实在不行报警吧:当 fielddata memory usage > 10GB → 告警;当 breaker tripped count > 0 → 紧急告警
    • 心要用在关键时刻,不屈小节:聚合用 .keyword,禁用 text 的 fielddata(8+默认禁了)
复制代码
  // 正确 mapping
  "message": {
    "type": "text",
    "fields": {
      "keyword": { "type": "keyword", "ignore_above": 256 }
    }
  }
  // 聚合查 message.keyword,不碰堆内存

😅 "你给 ES 32G 内存,它还你一个 OOM ------ 这叫好心当了驴肝肺"

附赠一个咱家的配置吧

Elasticsearch 8.x 生产环境推荐的内存安全配置

1、config/jvm.options(JVM 层)

复制代码
##################################################################
## JVM Heap Size (关键!)
## 原则:堆 ≤ 30GB,且 ≤ 物理内存的 50%
## 示例:64GB 机器 → -Xms30g -Xmx30g
##################################################################
-Xms30g
-Xmx30g

##################################################################
## GC 策略(ES 8.x 默认 G1GC,无需改)
## 不要手动指定 -XX:+UseG1GC(8.x 已默认)
##################################################################
# -XX:+UseG1GC  # ← ES 8.x 已默认,无需重复

##################################################################
## 内存保护(防止指针膨胀 & OOM)
##################################################################
# 启用压缩普通对象指针(Compressed Oops)------堆 ≤32GB 时自动生效
-XX:+UseCompressedOops
# 禁用显式 GC(防止 System.gc() 触发 Full GC)
-XX:+DisableExplicitGC
# G1GC 优化(官方推荐)
-XX:G1HeapRegionSize=16m
-XX:InitiatingHeapOccupancyPercent=30

##################################################################
## 监控与诊断(可选但推荐)
##################################################################
# OOM 时生成 heap dump(谨慎!可能很大)
# -XX:+HeapDumpOnOutOfMemoryError
# -XX:HeapDumpPath=/var/lib/elasticsearch
# GC 日志(ES 8.x 默认输出到 logs/gc.log,无需额外配置)
  • 如果机器内存 < 64GB,请按比例调整(如 32GB 机器 → -Xms16g -Xmx16g)对半吧

2、config/elasticsearch.yml(ES 应用层)

复制代码
# ======================== 内存与安全 ========================
# 锁定内存,防止 swap(必须配合系统设置)
bootstrap.memory_lock: true

# 熔断器:防止单个请求吃光内存(关键!)
indices.breaker.request.limit: 40%        # 单次请求最多用 40% 堆
indices.breaker.fielddata.limit: 20%      # fielddata 最多 20% 堆
indices.breaker.total.limit: 70%          # 所有 breaker 总和上限

# 网络缓冲区熔断(防 Bulk 压垮)
network.breaker.inflight.requests.limit: 50%

# ======================== fielddata 防护 ========================
# 全局禁止 text 字段加载 fielddata(ES 8.x 默认已禁,双重保险)
index.fielddata.cache.expire: 0s
index.fielddata.cache.size: 0

# ======================== 其他关键配置 ========================
# 线程池队列大小(防拒绝)
thread_pool:
  write:
    queue_size: 2000
  search:
    queue_size: 2000

# 磁盘水位(防只读)
cluster.routing.allocation.disk.watermark.low: 85%
cluster.routing.allocation.disk.watermark.high: 90%
cluster.routing.allocation.disk.watermark.flood_stage: 95%

# 安全(ES 8.x 默认启用)
xpack.security.enabled: true
xpack.monitoring.collection.enabled: true

3、其他

1、关闭SWAP

  • 临时 sudo swapoff -a

  • 永久:注释 /etc/fstab 中的 swap 行

2、增大文件描符 & 内存锁限制:其他场景也有用哦

编辑 /etc/security/limits.conf:英文的重要性体现一下下

  • elasticsearch soft nofile 65536
  • elasticsearch hard nofile 65536
  • elasticsearch soft memlock unlimited
  • elasticsearch hard memlock unlimited

3、验证memory lock,就是看看日志有没有,此刻安排眼线的重要性略显一二

复制代码
[INFO][o.e.b.BootstrapChecks] [node-1] bound or publishing to a non-loopback address, 
enforcing bootstrap checks
[INFO][o.e.b.BootstrapChecks] [node-1] memory locking requested for elasticsearch process but not enabled

看看memory locking ... not enabled 没配好🤣

相关推荐
忆~遂愿8 小时前
Runtime 上下文管理:计算实例的生命周期、延迟最小化与上下文切换优化
java·大数据·开发语言·人工智能·docker
Elastic 中国社区官方博客8 小时前
使用 Groq 与 Elasticsearch 进行智能查询
大数据·数据库·人工智能·elasticsearch·搜索引擎·ai·全文检索
BJ_Bonree9 小时前
4月17日,博睿数据受邀出席GOPS全球运维大会2026 · 深圳站!
大数据·运维·人工智能
张彦峰ZYF9 小时前
一套「策略化 Elasticsearch 召回平台」架构设计思路
大数据·elasticsearch·搜索引擎
Giggle12189 小时前
外卖 O2O 系统怎么选?从架构到部署方式的完整拆解
大数据·架构
九.九9 小时前
CANN 算子生态的底层安全与驱动依赖:固件校验与算子安全边界的强化
大数据·数据库·安全
Coder个人博客15 小时前
Linux6.19-ARM64 mm mmu子模块深入分析
大数据·linux·车载系统·系统架构·系统安全·鸿蒙系统
财经三剑客19 小时前
AI元年,春节出行安全有了更好的答案
大数据·人工智能·安全
岁岁种桃花儿20 小时前
Flink CDC从入门到上天系列第一篇:Flink CDC简易应用
大数据·架构·flink