跨节点HugePages生效需先确认NUMA架构并逐节点配置:运行numactl --hardware查节点数,再分别向/sys/devices/system/node/node*/hugepages/写入nr_hugepages值,禁用sysctl全局设置,改用systemd unit按节点初始化,并用numactl绑定进程验证。
确认节点是否启用 NUMA 并识别跨节点大页分配路径
跨节点 hugepages 生效的前提是内核识别到 numa 架构,且 vm.nr_hugepages 的分配行为受 numa_balancing 和 /proc/sys/vm/hugetlb_shm_group 等机制影响。不检查 numa 拓扑就调参数,大概率出现部分节点分配失败、cat /proc/meminfo | grep huge 显示总数对但各节点 hugepages_free 不均衡。
- 先运行
numactl --hardware,确认节点数(如available: 2 nodes (0-1))和每个节点的内存容量 - 检查
/sys/devices/system/node/node*/meminfo中各节点的HugePages_Total和HugePages_Free,不是只看全局/proc/meminfo - 若使用
libvirt或QEMU,需确保<memorybacking><hugepages></hugepages><numatune><memory></memory></numatune></memorybacking>配置显式绑定节点,否则默认可能只在 node 0 分配
统一设置所有节点的 vm.nr_hugepages 值要分步而非“一刀切”
直接在所有节点执行 echo 1024 > /proc/sys/vm/nr_hugepages 不等于跨节点均分 —— 内核按当前可用内存动态分配,node 1 内存不足时会静默失败,dmesg | grep -i huge 可能显示 hugetlb: failed to allocate page on node 1。
- 先清空:在每个节点分别执行
echo 0 > /proc/sys/vm/nr_hugepages,避免残留碎片干扰 - 再按节点逐个设:比如 node 0 有 64GB 可用内存,node 1 有 32GB,按比例设为
echo 768 > /sys/devices/system/node/node0/hugepages/hugepages-2048kB/nr_hugepages和echo 256 > /sys/devices/system/node/node1/hugepages/hugepages-2048kB/nr_hugepages - 验证必须查节点级路径:
cat /sys/devices/system/node/node0/hugepages/hugepages-2048kB/free_hugepages,不能只信/proc/sys/vm/nr_hugepages
永久生效需绕过 systemd-sysctl 的“全局覆盖”陷阱
/etc/sysctl.conf 里的 vm.nr_hugepages = 1024 会被 systemd-sysctl 加载为全局值,它不理解 NUMA 节点粒度,导致启动后所有大页都挤在 node 0 —— 这是生产环境最常被忽略的兼容性断点。
- 禁用 sysctl 全局设置:注释掉
vm.nr_hugepages行,改用systemdunit 在 multi-user.target 后启动脚本 - 写一个
/usr/local/bin/setup-hugepages.sh,用for node in /sys/devices/system/node/node*; do echo 256 > $node/hugepages/hugepages-2048kB/nr_hugepages; done - 配套 unit 文件里加
After=multi-user.target和WantedBy=multi-user.target,确保 NUMA 设备已初始化完成
验证跨节点分配是否真实生效的关键命令
很多团队用 grep Huge /proc/meminfo 就算通过,但其实没验证进程是否真从指定节点获取大页 —— 特别是 mmap(MAP_HUGETLB) 或 shmget(..., SHM_HUGETLB) 场景下,缺 NUMA 绑定会 fallback 到普通页。
- 启动测试进程前,用
numactl --cpunodebind=0 --membind=0 your_app强制绑定;否则即使大页存在,也可能跨节点访问造成延迟飙升 - 运行中查
cat /proc/<pid>/numa_maps | grep huge</pid>,输出行里应含huge=N0=256 N1=0这类明确节点计数,而不是只有huge标志 - 对比
cat /sys/devices/system/node/node0/meminfo | grep Huge和node1的差值变化,确认分配动作确实落在目标节点
跨节点 HugePages 不是设完参数就自动均衡的,它依赖内核 NUMA 初始化顺序、内存水位、以及用户态是否显式绑定。最容易被跳过的其实是启动脚本里对 /sys/devices/system/node/ 下各节点路径的逐个写入 —— 少一个节点,那个节点的大页池就是空的。










