Elasticsearch 8.x 启动失败因 vm.max_map_count 默认值65530低于要求的262144,需通过 sysctl -w 临时调整或修改 /etc/sysctl.conf 永久生效,并配套设置 ulimit -n、ulimit -u 和 swapoff。

为什么 Elasticsearch 启动报 vm.max_map_count 不足
Elasticsearch 8.x 默认要求 vm.max_map_count ≥ 262144,否则在 Bootstrap Checks 阶段直接退出,日志里明确出现:bootstrap check failure [1] of [1]: max virtual memory areas vm.max_map_count [65530] is too low, increase to at least [262144]。这不是警告,是硬性拦截——哪怕其他配置全对,这个值不够,进程就起不来。
根本原因是 ES 大量使用 mmap 加载索引文件(每个 segment、每个倒排文件都对应一个或多个 VMA),而默认内核值 65536 在中等规模集群下很快耗尽。注意:这和物理内存大小无关,只和进程能创建的虚拟内存区域数量有关。
临时调高 vm.max_map_count 立即生效
执行命令即可让当前运行的内核立刻接受新值:
sysctl -w vm.max_map_count=262144
验证是否生效:
sysctl -a | grep vm.max_map_count
常见误区:
-
sysctl -w只影响当前会话,重启后失效 - 必须用 root 权限执行,普通用户会提示
Permission denied - 如果容器里执行该命令,宿主机参数未改,容器重启后仍可能恢复旧值(取决于是否挂载
/proc/sys)
永久生效要改 /etc/sysctl.conf
编辑系统级配置文件,确保每次启动都加载:
Linux 安全审计工具,检查 SSH 配置、开放/监听端口、防火墙规则(ufw/iptables/nftables)、失败登录尝试、sudoers 权限...
echo "vm.max_map_count = 262144" >> /etc/sysctl.conf
然后加载全部配置(不只是刚加的那行):
sysctl -p
关键检查点:
- 确认没有拼写错误,比如写成
vm.max_map_count=262144(等号前后不能有空格)或漏掉= - 某些发行版(如 CentOS Stream 9)可能需额外执行
systemctl restart systemd-sysctl才能确保生效 - 若用 Docker 部署,仅改宿主机
/etc/sysctl.conf不够,还需在docker run时加--sysctl vm.max_map_count=262144,或在docker-compose.yml的sysctls字段声明
别忘了配套调 ulimit -n 和关 swap
vm.max_map_count 不是孤立参数。Elasticsearch 同时依赖:
-
ulimit -n 65535:文件描述符上限,否则打开大量 shard 或 index 时触发Too many open files -
ulimit -u 4096:单用户最大进程/线程数,避免因并发线程过多被限制 -
swapoff -a:ES 明确禁止 swap,否则 GC 行为不可控;即使设了bootstrap.memory_lock: true,swap 未关也会导致启动失败
这些限制在 systemd 服务中容易被忽略——ES 用 systemctl 启动时,ulimit 值默认继承自 systemd 全局设置,需在 /etc/systemd/system/elasticsearch.service.d/override.conf 中显式配置 LimitNOFILE=65535 和 LimitNPROC=4096。
真正容易被跳过的,是容器场景下对宿主机参数的双重确认:既要改 /etc/sysctl.conf,也要在容器启动时透传;既要设 vm.max_map_count,也不能漏掉 memlock 和 nofile 的 cgroup 限制。










