Linux服务器NUMA架构调优与跨节点内存访问延迟优化

NUMA架构对服务器性能的基础影响

现代多路服务器普遍采用NUMA(Non-Uniform Memory Access)架构,每个CPU插槽拥有本地内存控制器,访问本地节点的内存延迟远低于跨节点访问。在双路EPYC或Xeon服务器上,本地内存访问延迟约80-120ns,而跨节点访问延迟可达150-250ns,差异超过一倍。数据库、消息队列等内存密集型工作负载如果忽视NUMA拓扑,性能损失可达20%-40%。

NUMA节点的数量取决于物理CPU插槽和CCX/CHM布局。AMD EPYC 9004系列处理器每颗CPU包含4个CCD,每个CCD包含2个Core Complex,单颗CPU自身就呈现4节点NUMA拓扑;双路配置下系统呈现8个NUMA节点,跨节点访问链路更为复杂。

NUMA拓扑发现与延迟矩阵分析

调优的第一步是准确理解系统的NUMA拓扑:

# 查看NUMA节点与CPU亲和性
numactl --hardware

# 查看每个NUMA节点的内存使用
numastat -m

# 安装并测量节点间延迟矩阵
apt install numactl latency-topology
# 或使用Intel Memory Latency Checker
./mlc --loaded_latency -X

Intel MLC的输出会给出每对NUMA节点之间的内存访问延迟矩阵。典型双路Xeon Sapphire Rapids的延迟矩阵:

Numa node 0: 82ns (local)
Numa node 1: 145ns (remote, same socket)
Numa node 2: 195ns (remote, cross socket)
Numa node 3: 190ns (remote, cross socket)

跨Socket访问延迟比同Socket跨节点高出约35%-50%,这是因为跨Socket需要经过UPI/XGMI互连链路。了解这个矩阵是后续所有调优决策的基础。

进程与内存绑定的NUMA策略

Linux提供了numactl命令来控制进程的NUMA亲和性策略,核心参数包括:

--cpunodebind=N:将进程绑定到NUMA节点N的CPU核心上执行
--membind=N:限制进程只能在NUMA节点N分配内存
--preferred=N:优先在节点N分配内存,不足时回退到其他节点
--interleave=all:在所有节点间交叉分配内存

不同场景的最优策略:

# MySQL数据库:绑定到单节点,避免跨节点访问
numactl --cpunodebind=0 --membind=0 mysqld --defaults-file=/etc/mysql/my.cnf

# Redis实例:绑定到单节点,充分利用本地内存带宽
numactl --cpunodebind=1 --membind=1 redis-server /etc/redis/redis.conf

# 多线程应用(如Java JVM):交叉分配保证容量
numactl --interleave=all java -Xms32g -Xmx32g -jar app.jar

关键原则是:内存密集型单实例应用尽量绑定到单节点(membind),多实例部署时每个实例独占一个节点,避免内存竞争和跨节点访问。

MySQL的NUMA优化实战

MySQL是NUMA敏感型应用的典型代表。InnoDB Buffer Pool默认在所有NUMA节点间分配内存,导致大量跨节点访问。优化方案:

# 1. 绑定到NUMA节点0
numactl --cpunodebind=0 --membind=0 mysqld &

# 2. 配置Buffer Pool实例数等于NUMA节点数
[mysqld]
innodb_buffer_pool_instances = 4
innodb_buffer_pool_size = 64G

# 3. 开启NUMA感知的内存分配(MySQL 8.0+)
[mysqld]
innodb_numa_interleave = ON

实测在双路EPYC 9654(192核/4NUMA节点)服务器上,48GB Buffer Pool场景,TPS从绑核前的28,000提升到绑核后的36,500,提升幅度约30%。提升来源主要是减少了Buffer Pool页面扫描时的跨节点访存延迟。

中断亲和性与网卡NUMA对齐

网络密集型场景中,网卡中断处理如果发生在远端NUMA节点,会引入额外的跨节点延迟。高吞吐场景需对齐网卡与处理线程的NUMA位置:

# 查看网卡所在NUMA节点
cat /sys/class/net/eth0/device/numa_node

# 使用set_irq_affinity脚本设置中断亲和性
./set_irq_affinity 0 eth0

# 使用DPDK绑定网卡到特定NUMA节点
dpdk-devbind -b vfio-pci 0000:3b:00.0
numactl --cpunodebind=0 --membind=0 ./dpdk-app -l 0-15

10G网卡场景下,中断亲和性优化可使单连接延迟降低15-20微秒,P99延迟降低约30%。25G/100G网卡场景效果更为显著。

内核参数与透明大页的NUMA影响

透明大页(THP)在NUMA环境下行为需要特别关注。THP的khugepaged守护进程在合并页面时可能将跨节点的4KB页面合并到远端节点的大页中,反而增大延迟。建议内存密集型应用使用显式大页:

# 关闭透明大页的defrag(保留THP但禁用同步整理)
echo never > /sys/kernel/mm/transparent_hugepage/defrag

# 分配显式大页并绑定到NUMA节点
echo 8192 > /sys/devices/system/node/node0/hugepages/hugepages-2048kB/nr_hugepages
echo 8192 > /sys/devices/system/node/node1/hugepages/hugepages-2048kB/nr_hugepages

# MySQL使用大页
[mysqld]
large-pages

显式大页在分配时就遵循NUMA策略,不会出现THP跨节点合并的问题。对于Oracle、PostgreSQL等数据库同样适用。

原创文章,作者:小编,如若转载,请注明出处:https://www.yunthe.com/linux-fu-wu-qi-numa-jia-gou-diao-you-yu-kua-jie-dian-nei/

(0)
小编小编
上一篇 8小时前
下一篇 8小时前

相关推荐