NUMA 架构下,MySQL 实例跨节点访问内存延迟增加 30%,如何绑定
解读
面试官给出“延迟增加 30%”这一量化指标,目的是验证候选人是否真正在生产环境排查过 NUMA 引发的“远端内存”问题,而不仅仅背诵概念。国内互联网/金融/运营商的 MySQL 大多部署在 2~8 路鲲鹏、海光或 Intel 物理机上,操作系统以 CentOS 7/8、openEuler、AliLinux 为主,默认 NUMA 平衡策略常把 mysqld 的内存摊到所有节点,导致:
- 跨节点内存访问时延高,QPS 下跌;
- 节点内存不足时触发直接回收,出现“抖动尖刺”;
- perf/top 看到 %node0/1 远端内存访问占比高,但业务 SQL 本身无慢查询。
因此,考点聚焦在“如何借助 OS 级绑定手段,把 mysqld 进程、线程、内存三者固定到同一个 NUMA 节点,并给出可落地的验证步骤”。
知识点
- NUMA 拓扑查看:lscpu、numactl --hardware、lstopo(hwloc 包);
- 内存分配策略:mpol(内存策略)、zone_reclaim_mode、numa_balancing;
- CPU 绑定:taskset、systemd CPUAffinity、numactl --cpunodebind;
- 内存绑定:numactl --membind、--preferred、--localalloc;
- MySQL 启动封装:在 mysqld_safe 或 systemd 单元里注入 numactl;
- 线程级绑定:Linux 2.6+ 支持 sched_setaffinity,MySQL 8.0 可开启 innodb_numa_interleave=0 配合 --membind;
- 验证指标:/proc/vmstat 的 numa_hint_faults、numa_foreign、perf stat -e node-loads/node-stores,以及 sysbench 的 95th latency;
- 回退方案:若实例大于单节点内存,采用“多实例+分片”或“interleave all”策略,并评估跨节点代价。
答案
“我在 XX 支付核心账务系统遇到过同样问题,64 核 256 GB 的双路 Intel 服务器,sysbench oltp_read_write 压到 16 k QPS 时,P95 延迟从 18 ms 涨到 24 ms,perf 显示 38% 的内存访问落在远端节点。排查步骤如下:
- 确认拓扑:numactl --hardware 看到 Node0 32C/128G,Node1 32C/128G,mysqld 进程被调度到 Node0,但内存占用 140 GB,已溢出到 Node1。
- 关闭自动平衡:echo 0 > /proc/sys/kernel/numa_balancing,防止运行时再次漂移。
- 选择绑定策略:因实例大小(120 GB)小于单节点 128 GB,采用“单节点独占”方案,把 CPU+内存全部固定到 Node0。
- 修改 systemd 单元:
[Service]
ExecStartPre=/usr/bin/numactl --cpunodebind=0 --membind=0 /usr/bin/mysqld_pre_systemd
ExecStart=/usr/bin/numactl --cpunodebind=0 --membind=0 /usr/sbin/mysqld $MYSQLD_OPTS
CPUAffinity=0-31
同时关闭透明大页:echo never > /sys/kernel/mm/transparent_hugepage/enabled。 - 重启实例后,通过
watch -n1 'cat /proc/$(pidof mysqld)/numa_maps | grep N1 | wc -l'确认远端页为 0;sysbench 复测,P95 延迟从 24 ms 降到 17 ms,跨节点访问占比降到 1.2%,QPS 提升 22%,达到 SLA 要求。 - 上线后写 Ansible 模板,批量推送到 200+ 台 MySQL 主机,灰度观察一周无异常,纳入性能基线。
如果实例内存超过单节点,我会改用‘多实例分片’或‘interleave=all’,并在业务低峰做压测,评估跨节点 30% 延迟是否可接受,再决定是否拆分。”
拓展思考
- 云化场景:在 KVM 或容器里,NUMA 绑定需要宿主机开启 vCPU pinning 与 memory zones,Kubernetes 可用 TopologyManager + kubelet CPUManagerPolicy=static,验证手段是
kubectl describe node看到 guaranteed 容器拿到同一 socket 资源。 - ARM 鲲鹏:其 NUMA 节点间延迟差异比 Intel 更大,绑定收益可达 40% 以上,但需同步关闭 ARM64 的 64K 页表特性,避免内存浪费。
- 动态热点:对于夜间批处理或秒杀场景,可写定时脚本在业务高峰前
numactl --preferred临时绑定,峰后释放,兼顾资源利用率。 - 监控闭环:把
/sys/devices/system/node/node*/numastat的 numa_foreign、numa_hit 采集到 Prometheus,配置告警阈值:numa_foreign > 5% 且 p99 latency 上涨 > 10% 即自动发工单,让绑定策略成为“可观测、可回滚”的常态化运维动作。