Elasticsearch 7.9.3 内存充足却报无法分配内存且集群变红问题咨询
根因分析
你遇到的java.io.IOException: Cannot allocate memory报错发生在ES translog刷盘调用系统文件强制同步接口的阶段,即使系统显示可用内存充足,本质是内核态内存资源不足触发的分配失败,常见触发原因如下:
- 内核页缓存/缓冲区耗尽:你观测到的空闲内存是用户态可用内存,translog刷盘操作需要申请内核态的IO缓冲区资源,当节点写入量突增、大量分片同时做translog同步或者段文件合并时,内核缓冲区被占满就会触发该报错。
vm.max_map_count参数配置不满足ES要求:ES运行要求该内核参数至少为262144,该参数限制了单进程能使用的内存映射区域数量,配置过低时,translog、Lucene段文件的大量内存映射操作会触发内存分配失败。- 系统内存过量使用策略限制:如果
vm.overcommit_memory配置为2,操作系统会严格限制进程内存申请总量,即使存在空闲内存,只要申请量超出系统预设阈值也会直接拒绝分配。 - 单节点分片数过载:过多分片同时执行数据写入、分片恢复操作会带来集中的IO和内存申请请求,快速耗尽内核态内存资源。
解决方案
- 调整内核参数:执行
sysctl vm.max_map_count查看当前配置,如果低于262144,执行sysctl -w vm.max_map_count=262144临时生效;如需永久生效,在/etc/sysctl.conf文件中添加vm.max_map_count = 262144,执行sysctl -p加载配置。 - 优化内存过量使用策略:执行
sysctl vm.overcommit_memory查看当前值,若为2建议调整为1,执行sysctl -w vm.overcommit_memory=1临时生效,同样写入/etc/sysctl.conf永久生效,允许内核合理超量分配内存。 - 降低translog刷盘频率:如果业务允许节点宕机时丢失秒级数据,可将索引的
index.translog.durability配置从默认的request改为async,同时调整index.translog.sync_interval为10s~30s,减少频繁刷盘带来的内核资源占用。 - 控制单节点分片规模:7.x版本ES建议单节点分片数不超过「节点堆内存大小(GB)*20」,例如16G堆内存的节点最多承载320个分片,及时清理无用索引,拆分分片数过多的大索引降低单节点负载。
- 恢复异常分片:确认索引数据无损坏的前提下,可手动执行分片reroute操作,或临时关闭非核心索引释放资源后,重新开启分片分配功能恢复未分配分片。
内容的提问来源于stack exchange,提问作者user17515848
相关产品推荐
相关产品推荐

