在使用Docker运行Elasticsearch(ES)时,可能会遇到内存不足的问题,导致ES无法启动。以下是一次完整的排查和解决过程。
问题描述
在启动ES时,日志提示如下错误:
# Native memory allocation (mmap) failed to map 5368709120 bytes for committing reserved memory.
# There is insufficient memory for the Java Runtime Environment to continue.
通过进一步检查,发现Swap空间已满,内存也几乎耗尽。
环境信息
- 主机内存总量:63G
- Swap空间:2G(已满)
- 主要运行的进程:
mongod
(占用14.8GB内存)java -jar parse_gx_20210903.jar
(占用2.7GB内存)- 多个
mongosh
进程(每个占用约350MB内存)
排查步骤
-
检查内存和Swap使用情况
使用以下命令查看主机的内存和Swap空间:
free -h
输出结果:
total used free shared buff/cache available Mem: 63G 30G 4.8G 24G 28G 1.7G Swap: 2.0G 2.0G 0B
字段含义说明
-
total: 总内存大小。
-
used: 已使用的内存量。
-
free: 空闲的内存量。
-
shared: 被共享内存占用的大小。
-
buff/cache: 系统用于缓冲区和缓存的内存量。
-
available: 可用内存量,这个值比
free
更准确,因为它考虑了缓存可以被释放的情况。 -
Swap空间已满。
-
可用内存仅剩1.7G,说明内存压力较大。
-
-
列出高内存占用进程
使用以下命令按内存占用排序列出进程:
ps aux --sort=-%mem | head -n 15
输出部分内容:
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND root 97476 17.2 22.3 16422848 14817344 ? SLsl 2023 92351:21 mongod -f /mongo/config.conf root 16140 0.5 4.1 21645120 2755200 ? Sl 2024 2948:47 java -jar parse_gx_20210903.jar root 1642 0.0 1.4 1590720 980608 ? Ssl 2022 97:10 /usr/sbin/rsyslogd -n ...
-
分析结果
mongod
进程占用内存最多,为14.8GB。- 一个Java进程占用2.7GB。
- 多个
mongosh
进程共占用约4GB。
解决方案
-
释放内存占用
暂时停止一些非必要的服务来释放内存。
systemctl stop mongod
-
增加Swap空间
为避免未来出现类似问题,可以增加Swap空间。
# 创建一个新的Swap文件 dd if=/dev/zero of=/swapfile bs=1G count=4 chmod 600 /swapfile mkswap /swapfile swapon /swapfile
检查是否生效:
free -h
-
调整Elasticsearch的内存配置
如果ES仍然报错,可以调整其JVM配置文件(
jvm.options
),降低内存需求。-Xms2g -Xmx2g
-
重启下mongo服务释放下内存
docker restart mongo
-
重启服务
释放内存或增加Swap后,重启Elasticsearch:
docker restart elasticsearch
总结
通过上述步骤,我们成功解决了ES因内存不足无法启动的问题。总结关键点:
- 定期监控内存和Swap使用情况。
- 合理规划主机资源,避免服务之间竞争内存。
- 增加Swap空间作为应急方案。
- 重启占用内存大的mongo服务,可以释放一定内存
- 优化ES配置,降低内存占用。