ES报错too-many-open-files解决

ElasticSearch 服务挂了,挂可不是进程没了,因为有 Supervisor 保护,而是服务不可用了。以前曾经出现过一次因为 ES_HEAP_SIZE 设置不当导致的服务不可用故障,于是我惯性的判断应该还是 ES_HEAP_SIZE 的问题,不过登录服务器后发现日志里显示大量的「Too many open files」错误信息。那么 ElasticSearch 设置的最大文件数到底是多少呢?可以通过 proc 确认:

shell> cat /proc/<PID>/limits

结果是「4096」,我们还可以进一步看看 ElasticSearch 打开的都是什么东西:

shell> ls /proc/<PID>/fd

问题看上去非常简单,只要加大相应的配置项应该就可以了。此配置在 ElasticSearch 里叫做 MAX_OPEN_FILES,可惜配置后发现无效。按我的经验,通常此类问题多半是由于操作系统限制所致,可是检查结果一切正常:

shell> cat /etc/security/limits.conf

* soft nofile 65535
* hard nofile 65535

问题进入了死胡同,于是我开始尝试找一些奇技淫巧看看能不能先尽快缓解一下,我搜索到 @-神仙- 的一篇文章:动态修改运行中进程的 rlimit,里面介绍了如何动态修改阈值的方法,虽然我测试时都显示成功了,可惜 ElasticSearch 还是不能正常工作:

shell> echo -n 'Max open files=65535:65535' > /proc/<PID>/limits

此外,我还检查了系统内核参数 fs.file-nr 及 fs.file-max,总之一切和文件有关的参数都查了,甚至在启动脚本里硬编码「ulimit -n 65535」,但一切努力都显得毫无意义。正当山穷水尽疑无路的时候,同事 @轩脉刃 一语道破玄机:关闭 Supervisor 的进程管理机制,改用手动方式启动 ElasticSearch 进程试试看。结果一切恢复正常。为什么会这样呢?因为使用 Supervisor 的进程管理机制,它会作为父进程 FORK 出子进程,也就是 ElasticSearch 进程,鉴于父子关系,子进程允许打开的最大文件数不能超过父进程的阈值限制,但是 Supervisor 中 minfds 指令缺省设置的允许打开的最大文件数过小,进而导致 ElasticSearch 进程出现故障。此故障原因本来非常简单,但我却陷入了经验主义的固定思维,值得反思。


在Linux下面部署应用的时候,有时候会遇上Socket/File: Can’t open so many files的问题;这个值也会影响服务器的最大并发数,其实Linux是有文件句柄限制的,而且Linux默认不是很高,一般都是1024,生产服务器用其实很容易就达到这个数量。下面说的是,如何通过正解配置来改正这个系统默认值。

查看方法

我们可以用ulimit -a来查看所有限制值
[root@centos5 ~]# ulimit -a
core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
max nice                        (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 4096
max locked memory       (kbytes, -l) 32
max memory size         (kbytes, -m) unlimited
open files                      (-n) 1024
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
max rt priority                 (-r) 0
stack size              (kbytes, -s) 10240
cpu time               (seconds, -t) unlimited
max user processes              (-u) 4096
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited||<

其中 "open files (-n) 1024 "是Linux操作系统对一个进程打开的文件句柄数量的限制

(也包含打开的SOCKET数量,可影响MySQL的并发连接数目)。

 

正确的做法,应该是修改/etc/security/limits.conf
里面有很详细的注释,比如
Hadoop  soft   nofile   32768
hadoop hard nofile 65536

hadoop soft   nproc   32768
hadoop hard nproc 65536
就可以将文件句柄限制统一改成软32768,硬65536。配置文件最前面的是指domain,设置为星号代表全局,另外你也可以针对不同的用户做出不同的限制。

注意:这个当中的硬限制是实际的限制,而软限制,是warnning限制,只会做出warning;其实ulimit命令本身就有分软硬设置,加-H就是硬,加-S就是软
默认显示的是软限制,如果运行ulimit命令修改的时候没有加上的话,就是两个参数一起改变。

RHE6及以后 nproc的修改在/etc/security/limits.d/90-nproc.conf中


补充说明:

soft nproc: 可打开的文件描述符的最大数(软限制)

hard nproc: 可打开的文件描述符的最大数(硬限制)

soft nofile:单个用户可用的最大进程数量(软限制)

hard nofile:单个用户可用的最大进程数量(硬限制)



<think>好的,用户想了解Elasticsearch 8.7.1异常退出的原因和解决方案。首先,我需要回忆一下常见的ES异常退出情况。通常,内存问题是一个主要原因,比如JVM堆内存不足或者配置不当。用户可能没有正确设置-Xms和-Xmx参数,导致内存溢出。这时候需要检查日志中的OutOfMemoryError或者GC overhead limit exceeded之类的错误。根据引用2,用户启动时可能用了ES_JAVA_OPTS="-Xms256m -Xmx256m",但如果是数据量大的情况,256m可能不够,应该适当调大,比如512m或1g。 另一个可能的原因是文件描述符限制。Linux系统默认的文件描述符数目可能不够,导致ES无法打开足够的文件。需要查看日志中的“too many open files”错误,并建议用户修改系统限制,比如ulimit -n 65535或者修改/etc/security/limits.conf文件。 磁盘空间不足也是常见问题。ES写入数据时如果磁盘满了,就会退出。需要检查磁盘使用情况,清理空间或者增加存储。日志里可能会有“disk usage exceeded flood-stage watermark”之类的提示。 插件冲突也可能导致异常退出,特别是安装了不兼容的插件。用户提到引用4中的拼音分词插件,如果版本不匹配ES 8.7.1,可能引发问题。建议用户暂时移除插件,再测试是否稳定。 配置错误也不能忽视,比如elasticsearch.yml中的错误设置。引用2中用户挂载了配置文件,可能配置有误,比如网络设置、集群名称不一致等。需要检查配置文件语法,确保正确。 还有可能是系统环境问题,比如Docker容器资源不足。如果用户用Docker运行ES,内存或CPU限制过低,容器会被终止。引用2中的Docker命令设置了内存参数,但可能需要根据实际情况调整。此外,查看容器日志是否有OOM Killer的记录。 最后,版本兼容性问题,比如JDK版本不符合ES 8.7.1的要求。ES 8.x通常需要JDK 17,如果用户环境是旧版JDK,会导致启动失败。需要确认Java版本是否正确安装。 总结下来,用户需要逐步检查日志,定位具体错误信息,然后针对性地调整内存配置、系统限制、磁盘空间、插件兼容性、配置文件等。同时,结合用户提供的引用内容,特别是引用2中的Docker配置,可能需要优化资源分配,确保ES有足够的运行环境。</think>### Elasticsearch 8.7.1 异常退出分析与解决方案 #### 一、常见原因分析 1. **内存不足** Elasticsearch 默认使用 JVM 堆内存(通过 `-Xms` 和 `-Xmx` 配置)。若内存分配不足或超出物理内存限制,会导致进程崩溃。 - **日志特征**:`OutOfMemoryError`、`GC overhead limit exceeded` - **解决方案**:调整 `ES_JAVA_OPTS`,例如: ```bash -e ES_JAVA_OPTS="-Xms1g -Xmx1g" # 根据服务器内存调整[^2] ``` 2. **文件描述符限制** Linux 系统默认文件描述符数量较低,可能触发 Elasticsearch 异常。 - **日志特征**:`too many open files` - **解决方案**: ```bash ulimit -n 65535 # 临时生效 # 永久生效需修改 /etc/security/limits.conf[^1] ``` 3. **磁盘空间不足** 磁盘使用率超过阈值(默认95%)会导致 Elasticsearch 进入只读模式或崩溃。 - **日志特征**:`flood stage disk watermark [95%] exceeded` - **解决方案**:清理数据或扩展磁盘容量。 4. **插件冲突** 不兼容的插件(如拼音分词插件)可能引发稳定性问题[^4]。 - **日志特征**:`NoSuchMethodError` 或 `ClassNotFoundException` - **解决方案**:移除可疑插件后重启测试。 --- #### 二、日志排查步骤 1. **定位日志文件** Elasticsearch 日志默认位于 `logs/elasticsearch.log`(容器路径需映射到宿主机)。 2. **关键日志筛选** - 搜索 `ERROR`、`FATAL` 级别日志 - 检查最后几行日志的堆栈跟踪(Stack Trace) --- #### 三、典型场景解决方案 | 场景 | 操作 | |------|------| | **Docker 容器退出** | 检查容器资源限制:`docker inspect es7.8.1`,确保内存≥2GB[^2] | | **配置错误** | 验证 `elasticsearch.yml` 语法:`bin/elasticsearch -d -Ehttp.port=9200` | | **集群脑裂问题** | 单节点模式下添加 `discovery.type: single-node` | --- #### 四、进阶调试 1. **启用详细日志** 修改 `config/log4j2.properties`,设置 `logger.elasticsearch.level = trace`。 2. **堆内存转储分析** 通过 `jmap -dump:format=b,file=heap.hprof <pid>` 生成快照,使用 MAT 工具分析。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值