3. Linux 大页配置方法
大页(HugePages)是 DPDK 性能的基石。Linux 内核提供了三种配置大页的方式:临时配置(运行时调整)、永久配置(重启后生效)和启动时配置(内核引导参数)。三种方式适用于不同的运维场景,理解其差异是避免生产环境配置丢失的关键。
3.1 三种配置方式对比
| 配置方式 | 生效时机 | 持久性 | 适用场景 |
|---|---|---|---|
临时配置(/proc/sys/vm/nr_hugepages) |
立即生效 | 重启后丢失 | 快速验证、开发调试、临时调优 |
永久配置(/etc/sysctl.conf) |
重启后生效 / sysctl -p 立即加载 |
持久化 | 生产环境标准部署 |
启动时配置(hugepagesz= 内核参数) |
系统引导时分配 | 持久化(需修改引导加载器) | 需要 1G 巨页、早期内存预留、避免碎片化 |
最佳实践:生产环境推荐“启动时配置 + 永久配置”组合:启动时预留 1G 大页给 DPDK 数据面,永久配置保留 2MB 大页给控制面或辅助进程。
3.2 临时配置:/proc/sys/vm/nr_hugepages
通过写入 /proc 文件系统,可以立即调整大页数量,无需重启。这是开发阶段最常用的方法。
配置步骤
- 查看当前大页状态
# 查看系统大页信息
cat /proc/meminfo | grep -i huge
# 输出示例:
# AnonHugePages: 0 kB
# ShmemHugePages: 0 kB
# HugePages_Total: 0
# HugePages_Free: 0
# HugePages_Rsvd: 0
# HugePages_Surp: 0
# Hugepagesize: 2048 kB
- 分配 2MB 大页(以 1024 个为例)
# 分配 1024 个 2MB 大页,共 2GB
echo 1024 > /proc/sys/vm/nr_hugepages
# 验证分配结果
cat /proc/meminfo | grep HugePages_Total
# 期望输出:HugePages_Total: 1024
- 分配特定 NUMA 节点的大页
# 在 NUMA node0 上分配 512 个 2MB 大页
echo 512 > /sys/devices/system/node/node0/hugepages/hugepages-2048kB/nr_hugepages
# 在 NUMA node1 上分配 512 个 2MB 大页
echo 512 > /sys/devices/system/node/node1/hugepages/hugepages-2048kB/nr_hugepages
注意:临时配置在系统重启后失效。如果内存碎片严重,
echo 操作可能分配少于请求的数量,务必检查 HugePages_Total 确认实际分配值。
3.3 永久配置:/etc/sysctl.conf
将大页参数写入 /etc/sysctl.conf 或 /etc/sysctl.d/ 下的独立配置文件,实现重启后自动生效。
配置步骤
- 编辑 sysctl 配置文件
# 使用 root 权限编辑
vim /etc/sysctl.conf
# 添加以下行(分配 2048 个 2MB 大页,共 4GB)
vm.nr_hugepages = 2048
# 可选:设置大页池最小值,防止被回收
vm.nr_hugepages_mempolicy = 2048
- 立即加载配置(无需重启)
# 使配置立即生效
sysctl -p
# 验证
sysctl vm.nr_hugepages
# 输出:vm.nr_hugepages = 2048
- NUMA 感知的永久配置(推荐)
# 在 /etc/sysctl.d/99-hugepages.conf 中配置
# node0 分配 1024 个 2MB 大页
vm.nr_hugepages = 2048
# 注意:sysctl 不支持直接设置 per-node 参数,
# 需要在启动脚本中通过 echo 写入 /sys/devices/system/node/ 下的接口
生产建议:在
/etc/sysctl.d/ 下创建独立配置文件(如 99-dpdk-hugepages.conf),便于管理和回滚。配置格式为 vm.nr_hugepages = 数量。
3.4 启动时配置:hugepagesz= 内核参数
通过内核引导参数在系统启动早期预留大页,支持 1GB 巨页,避免运行时分配失败。需要修改 GRUB 配置。
配置步骤
- 编辑 GRUB 配置
# 编辑 /etc/default/grub
vim /etc/default/grub
# 找到 GRUB_CMDLINE_LINUX 行,添加大页参数
# 示例:预留 4 个 1GB 大页,8 个 2MB 大页
GRUB_CMDLINE_LINUX="... default_hugepagesz=1G hugepagesz=1G hugepages=4 hugepagesz=2M hugepages=8"
- 更新 GRUB 引导器
# 对于 BIOS 系统
grub2-mkconfig -o /boot/grub2/grub.cfg
# 对于 UEFI 系统
grub2-mkconfig -o /boot/efi/EFI/centos/grub.cfg
# 重启系统
reboot
- 验证启动时分配
# 重启后检查大页状态
cat /proc/meminfo | grep -E "HugePages_Total|Hugepagesize"
# 期望输出:
# HugePages_Total: 12 (4个1G + 8个2M)
# Hugepagesize: 1048576 kB (默认显示最后配置的页面大小)
# 查看 1G 大页的 NUMA 分布
cat /sys/devices/system/node/node*/hugepages/hugepages-1048576kB/nr_hugepages
关键约束:
default_hugepagesz必须与第一个hugepagesz=一致。- 1GB 大页只能在启动时预留,不支持运行时
echo分配。 - 不同架构支持的页面大小不同:x86_64 支持 2MB 和 1GB;ARM64 支持 64KB、2MB 和 1GB。
3.5 大页配置流程总览
3.6 配置验证与常见问题
验证清单
| 检查项 | 命令 | 预期结果 |
|---|---|---|
| 大页总数 | cat /proc/meminfo | grep HugePages_Total |
等于配置值 |
| 空闲大页 | cat /proc/meminfo | grep HugePages_Free |
大于等于 DPDK 需求 |
| NUMA 分布 | cat /sys/devices/system/node/node*/hugepages/hugepages-2048kB/nr_hugepages |
各节点数量符合预期 |
| 大页挂载 | mount | grep hugetlbfs |
显示挂载点和页面大小 |
| DPDK 检测 | dpdk-hugepages.py -s |
显示可用大页数量和大小 |
常见问题与解决
- 分配数量不足:检查
dmesg | grep huge查看内核是否因内存碎片拒绝分配。尝试启动时预留或减少其他内存占用。 - NUMA 节点分配不均:使用
numactl --hardware查看节点内存大小,按比例分配。DPDK 的--socket-mem参数需与 NUMA 大页分布匹配。 - 1G 大页未生效:确认 CPU 支持 1G 页面(
cat /proc/cpuinfo | grep pdpe1gb),且内核编译开启CONFIG_HUGETLB_PAGE和CONFIG_HUGETLBFS。 - 重启后配置丢失:检查
/etc/sysctl.conf语法错误,或 GRUB 配置未正确更新。运行sysctl -p测试加载。
快速诊断脚本:
#!/bin/bash
# 大页健康检查
echo "=== HugePages Info ==="
grep -E "HugePages_Total|HugePages_Free|Hugepagesize" /proc/meminfo
echo ""
echo "=== NUMA Distribution ==="
for node in /sys/devices/system/node/node*/hugepages/hugepages-2048kB; do
echo "$(basename $(dirname $(dirname $node))): $(cat $node/nr_hugepages)"
done
echo ""
echo "=== Mount Points ==="
mount | grep hugetlbfs
3.7 配置策略总结
选择配置方式的核心原则:1G 大页必须启动时预留,2MB 大页生产环境用永久配置,开发调试用临时配置。无论哪种方式,配置后务必通过 /proc/meminfo 和 NUMA 节点接口双重验证,确保 DPDK 运行时有足够的大页资源可用。