当前位置: 首页 > news >正文

Ceph OSD NUMA 亲和性、Page Cache 跨 NUMA 访问与绑核实践

环境:Ceph 14.2.18(Nautilus),双 NUMA 节点,56 核,42 OSD


一、Page Cache 是否有 NUMA 归属?

很多人认为 page cache 是全局的,没有 NUMA 归属。实际上page cache 的每一页都有 NUMA 归属,只是这个归属是隐式决定的,而不像进程那样可以显式设置。

1.1 Page Cache 页的 NUMA 分配机制

Linux 内核在将磁盘数据读入 page cache 时,会在处理该 IO 完成中断(IRQ)的 CPU 所在的 NUMA node上分配物理内存页:

磁盘 IO 完成 ↓ Block layer 触发 IRQ 完成回调 ↓ 由"当前处理该 IRQ 的 CPU"所在的 NUMA node 分配 page ↓ page cache 中这一页的物理内存归属于该 NUMA node

所以 page cache 页落在哪个 NUMA node,取决于两个因素:

  1. IRQ 亲和性(smp_affinity):磁盘中断绑定到哪些核上处理
  2. 触发 IO 的线程:部分场景(如同步读)是由触发 IO 的线程等待完成,page 在该线程所在的 NUMA node 分配

1.2 跨 NUMA 访问 page cache 的典型场景

场景一:OSD 线程在 NUMA0,但 IRQ 被调度到 NUMA1 处理

OSD 线程(NUMA0 核 #4)发起 pread ↓ 磁盘 IO 完成,IRQ 在 NUMA1 核 #5 处理 ↓ page cache 页分配在 NUMA1 ↓ OSD 线程(NUMA0)读取该页 → 跨 NUMA 内存访问

场景二:OSD 线程不绑核,在 NUMA0/NUMA1 之间漂移

第一次 IO:OSD 线程在 NUMA0 → page 分配在 NUMA0 ↓ 线程被调度器移到 NUMA1 核 ↓ 第二次读命中 page cache,但 page 在 NUMA0 → 跨 NUMA

场景三:多个 OSD 共享同一 SST 文件(BlueFSbluefs_buffered_io=true时)

OSD_A 的 RocksDB 与 OSD_B 同盘时(或共享 block.db 时) OSD_A 在 NUMA0 触发 IO → page 分配在 NUMA0 OSD_B 的线程在 NUMA1 → 读同一 page → 跨 NUMA

二、如何判断是否发生跨 NUMA 访问

2.1 方法一:numastat -p <pid>查看进程内存分布

# 获取 OSD 进程 PIDOSD_PID=$(pgrep-f"ceph-osd.*id 1334")# 查看 NUMA 内存分布numastat-p$OSD_PID

典型输出:

Per-node process memory usage (in MBs) for PID 12345 (ceph-osd) Node 0 Node 1 Total ----- ------ ----- Huge 0.00 0.00 0.00 Heap 412.30 389.50 801.80 ← 堆内存分散在两个 node Stack 0.06 0.02 0.08 Private 923.14 867.23 1790.37 ---------------- Total 1335.50 1256.75 2592.25

判断标准:如果 Node 0 的 OSD 进程在 Node 1 上有大量内存(Private > 100MB 且占比超过 30%),说明存在显著的跨 NUMA 内存访问。理想情况下,绑定到 NUMA0 的 OSD 几乎所有内存都应该在 Node 0。

2.2 方法二:查看线程的 CPU 分布

# 查看 OSD 进程所有线程跑在哪些核上ps-eLopid,tid,psr,comm|grep$(pgrep-f"ceph-osd.*1334")|head-30

输出中psr列是当前线程运行的 CPU 编号。对照本机的 NUMA 拓扑:

# 查看 NUMA 拓扑numactl--hardware# 或cat/sys/devices/system/node/node0/cpulist# NUMA0 的核列表cat/sys/devices/system/node/node1/cpulist# NUMA1 的核列表

以本机为例(偶数核 = NUMA0,奇数核 = NUMA1):

PID TID PSR COMMAND 12345 12345 0 ceph-osd ← NUMA0 12345 12346 3 tp_osd_tp ← NUMA1 ! 12345 12347 4 rocksdb:low ← NUMA0 12345 12348 15 msgr-worker ← NUMA1 !

同一个 OSD 进程的线程分散在两个 NUMA node,则这些线程之间共享的内存(RocksDB block cache、page cache、内存池)都会产生跨 NUMA 访问。

2.3 方法三:perf 硬件性能计数器(最精确)

# 监控远端 NUMA 内存访问占比perfstat-e\mem_load_retired.local_pmm,\mem_load_retired.remote_pmm,\mem_load_retired.local_dram,\mem_load_retired.remote_dram\-p$OSD_PIDsleep30

输出示例:

1,234,567 mem_load_retired.local_dram # 本地 NUMA DRAM 命中 897,234 mem_load_retired.remote_dram # 远端 NUMA DRAM 命中 ← 这个高说明跨 NUMA 严重

remote_dram/local_dram比值 > 30% 即说明跨 NUMA 访问严重。

2.4 方法四:/proc/pid/numa_maps详细页面分布

cat/proc/$OSD_PID/numa_maps|grep-v"^$"

输出格式:地址 策略 N0=页数 N1=页数 ...

7f1234000000 default N0=1024 N1=987 ← 这段匿名内存在两个 node 上都有分配 7f2345000000 default N0=2048 N1=0 ← 这段完全在 NUMA0,理想状态

N0 和 N1 的页数接近说明内存分配没有 NUMA 亲和性,大量跨 NUMA 访问几乎必然发生。

2.5 方法五:间接判断——查看 IRQ 亲和性

# 找到磁盘的 IRQ 号cat/proc/interrupts|grep-E"sdb|nvme"# 查看该 IRQ 的 CPU 亲和性掩码cat/proc/irq/<IRQ_NUM>/smp_affinity_list

如果磁盘 IRQ 绑定在 NUMA1 的核上,而 OSD 线程主要跑在 NUMA0,那么 page cache 页(由 IRQ 处理时分配)会在 NUMA1,OSD 读取时必然跨 NUMA。


三、IO 进程绑核的好处

3.1 消除跨 NUMA 内存访问延迟

这是绑核最核心的收益。

NUMA 本地访问延迟:~80ns NUMA 远端访问延迟:~150ns(约 1.9 倍) 以 generic_file_buffered_read 中的 copy_page_to_iter 为例: 操作:从 page cache 复制 4KB 数据到用户 buffer 本地 NUMA:4096 / 64 (cache line) × 80ns = ~5μs 跨 NUMA: 4096 / 64 × 150ns = ~10μs × 每次 RocksDB GET 读 1~3 个 block × 高峰期 42 OSD 并发大量 GET → 内存延迟开销累加非常可观

绑核(按 NUMA node 绑定)后,OSD 线程、其堆内存、page cache 页都在同一 NUMA node,内存访问延迟稳定在本地延迟。

3.2 提高 CPU Cache 命中率(L1/L2 Cache)

不绑核时,线程可能在每次调度后跑到不同的 CPU 核上:

调度前:线程在 Core #4,L1/L2 cache 里有 OSD 的热数据(onode cache、内存池指针) 调度后:线程被调度到 Core #12 → Core #12 的 L1/L2 cache 全是"冷"的,原有缓存全部失效 → 需要重新从 L3 cache 或内存加载数据

绑核后,线程长期在固定的一组 CPU 核上运行:

线程始终在 Core #4 和 Core #6(同一 NUMA node 的两个核)之间调度 → L2 cache(256KB/核)和共享 L3 cache(35MB/socket)持续命中 → 减少内存访问次数,降低 CPU 执行时间

3.3 减少 TLB 和 Context Switch 开销

线程跑到新核时,不仅 L1/L2 cache 失效,TLB(页表缓存)也需要刷新:

不绑核:线程频繁在不同核间迁移 → 每次迁移:TLB flush(清空页表缓存) → 后续内存访问需要重新 page walk(从 CR3 开始遍历页表) → 对于 OSD 这种内存访问密集的程序,TLB miss 率直接影响性能 绑核:线程在固定核上,TLB 长期有效 → 内存访问直接命中 TLB → page walk 次数大幅减少

3.4 配合 IRQ 亲和性实现端到端 NUMA 本地化

绑核后可以进一步将磁盘 IRQ 绑定到与 OSD 线程相同的 NUMA node:

# 将 sdb 的 IO 完成中断绑定到 NUMA0 的核(偶数核)echo"0,2,4,6,8,10,12,14">/proc/irq/<IRQ_NUM>/smp_affinity_list

实现完整的本地化链路:

OSD 线程(NUMA0)→ 发起 IO 磁盘 IRQ(NUMA0 核处理)→ page cache 页分配在 NUMA0 OSD 线程(NUMA0)→ 读 page cache → 本地 NUMA 访问

每个环节都在 NUMA0,没有任何远端内存访问。

3.5 降低尾延迟(p99/p999)

对于存储系统,尾延迟比平均延迟更重要。跨 NUMA 访问的延迟不稳定(~150ns 是均值,有时更高),是尾延迟抖动的主要来源之一。绑核后内存访问延迟稳定,p99/p999 延迟会明显收窄。

3.6 防止 CPU 竞争(多 OSD 共存场景)

你们的场景:42 OSD × ~10 线程 = 约 420 个线程,共享 56 个核。不绑核时,Linux 调度器可能把多个 OSD 的线程都堆在热点核上:

不绑核: Core #0 同时有 OSD_1321 的 tp_osd_tp、OSD_1334 的 msgr-worker、OSD_1342 的 rocksdb 线程 → 这些线程互相竞争 Core #0 的时间片 → 高 IO 峰值时,某个 OSD 的线程可能长时间等待调度 绑核(每 OSD 划分 1~2 个核): OSD_1321~1341:绑定 NUMA0 的 28 个核(每 OSD 约 1.3 核) OSD_1342~1362:绑定 NUMA1 的 28 个核(每 OSD 约 1.3 核) → 不同 OSD 的线程不再互相竞争,调度更可预期

四、Ceph OSD 现网是否需要绑核?

4.1 你们当前场景分析

硬件:Intel E5-2680 v4,双 NUMA,56 逻辑核(28 物理核 × 2 超线程) OSD:42 个 内存:95G 存储:LVM 部署,无独立 block.db

核资源测算

维度数据
每 OSD 平均可用核数56 / 42 ≈1.33 个逻辑核
每 OSD 典型线程数~10 个(tp_osd_tp、messenger、rocksdb、finisher 等)
总线程数42 × 10 ≈ 420 个线程
调度竞争比420 线程 / 56 核 =7.5 个线程/核

结论:CPU 资源已经偏紧,高 IO 压力下不绑核会导致严重的调度竞争。

4.2 建议:按 NUMA node 绑核(而非精确绑单核)

不建议精确绑到每个核(运维成本高,且 1.33 核/OSD 的情况下没有足够余量),建议按NUMA node 粒度绑核

NUMA node 0(28 个逻辑核:0,2,4,...,54)→ OSD 1321~1341(21 个 OSD) NUMA node 1(28 个逻辑核:1,3,5,...,55)→ OSD 1342~1362(21 个 OSD)

每个 NUMA node 的 28 核分给 21 个 OSD,平均 1.33 核/OSD,与不绑核时的总体比例相同,但消除了跨 NUMA 访问

4.3 绑核实现方式(systemd + numactl)

# 创建 override 目录mkdir-p/etc/systemd/system/ceph-osd@1321.service.d/# 写入绑核配置(绑到 NUMA0)cat>/etc/systemd/system/ceph-osd@1321.service.d/numa.conf<<EOF [Service] ExecStart= ExecStart=/usr/bin/numactl --cpunodebind=0 --membind=0 \ /usr/bin/ceph-osd -f --cluster ceph --id %i \ --setuser ceph --setgroup ceph EOFsystemctl daemon-reload systemctl restart ceph-osd@1321

--cpunodebind=0:CPU 只跑在 NUMA node 0 的核上
--membind=0:所有内存分配(堆、栈、mmap)优先从 NUMA node 0 分配

配套的 IRQ 绑核(找到对应磁盘的 IRQ):

# 查找磁盘对应的 IRQls/sys/block/sdb/device/cat/proc/interrupts|grep"sdb\|nvme"# 将 IRQ 绑到 NUMA0 的核(偶数核)echo"0,2,4,6,8,10,12,14,16,18,20,22,24,26">/proc/irq/<IRQ>/smp_affinity_list

4.4 绑核的代价与注意事项

代价说明缓解方式
运维复杂度增加OSD 上下线需要维护绑核配置写统一的 ansible playbook 管理
空闲 OSD 浪费 CPU某个 OSD 低负载时,绑定给它的核不能被其他 OSD 用只做 NUMA node 绑,不做精确核绑
绑核方案不合理可能更差把多个高负载 OSD 绑在 NUMA0,NUMA1 空闲按 OSD 数量均分到两个 NUMA node

4.5 优先级建议

绑核需要重启 OSD,涉及数据重平衡,操作成本较高。建议按以下顺序推进:

第一步(立即,无需重启): ceph config set osd bluefs_buffered_io false → 直接消除 copy_page_to_iter 的 CPU 开销 → 释放 page cache 重复缓存的内存 → 预期 CPU 使用率下降 10~30% 第二步(规划窗口期,需要重启 OSD): 按 NUMA node 绑核 + IRQ 亲和性调整 → 消除跨 NUMA 内存访问延迟 → 降低 p99/p999 尾延迟 → 长期运行稳定性提升 第三步(可选,配合第一步): 适当调大 bluestore_cache_size / rocksdb_cache_size → 去掉 page cache 双缓存后,确保 RocksDB block cache 覆盖热数据

五、总结

问题判断方法解决方案
page cache 是否有 NUMA 归属?有,由处理 IO IRQ 的 CPU 所在 NUMA node 决定合理设置 IRQ affinity
如何判断跨 NUMA?numastat -pps -eLo psrperf stat remote_dram绑核使 OSD 线程和 IRQ 在同一 NUMA node
不绑核的主要损耗L1/L2 cache 失效、TLB flush、跨 NUMA 内存延迟 ×2按 NUMA node 粒度绑核
你们现网需要绑核吗?是,42 OSD 共 56 核,调度竞争比 7.5:1,绑核收益显著NUMA0 绑 OSD 1321~1341,NUMA1 绑 OSD 1342~1362
http://www.cnnetsun.cn/news/2654893.html

相关文章:

  • 掌握AMD Ryzen处理器的终极武器:SMUDebugTool深度解析
  • 验收驱动提示词:让企业 AI 输出可控、可复用
  • Jellyfin Android TV终极配置指南:15分钟打造完美家庭影院体验
  • 别再只盯着路由模式了!天融信防火墙透明模式部署实战,零感知保护内网安全
  • 给程序员的气象学:用代码思维图解大气环流三圈模型(哈德来/费雷尔/极地环流)
  • 3步搞定飞书文档批量导出:告别手动下载的烦恼
  • 数学建模‘小白’避坑指南:如何从一份居民健康问卷中挖掘出靠谱结论?
  • AI Agent 越来越强,但谁来为它的行为负责?KYA 给出答案
  • 从智能镊子到LCR表:深入拆解‘交流响应法’与‘直流充放电法’如何各显神通
  • 输入冲突终结者:Hitboxer SOCD键盘重映射工具的架构解析与实战指南
  • Get-cookies.txt-LOCALLY:3分钟掌握浏览器Cookie本地导出终极指南
  • 如何用开源阅读鸿蒙版打造你的专属数字图书馆:5个步骤告别碎片化阅读
  • GPT-4深度解析:从MoE架构到智能体应用的技术跃迁
  • MyTV-Android:老旧电视重获新生的终极直播解决方案
  • 魔兽争霸3现代化改造指南:开源工具Warcraft Helper完全解析
  • 汽车技术趋势解析:从电动化、智能化到软件定义汽车的未来
  • CXLE83260H 高精度 LED 恒流驱动芯片
  • 异构图神经网络加速器的内存效率优化与硬件设计
  • 3步搞定番茄小说下载器:离线阅读全平台解决方案
  • 27考研石雷鹏作文|七步法网课PDF
  • DeepSeek LeetCode 2842. 统计一个字符串的 k 子序列美丽值最大的数目 TypeScript实现
  • 从GPT-Neo到FFmpeg:构建AI虚拟主播的完整技术栈解析
  • 现代网络安全实战框架:技术、流程与人员三大支柱解析
  • 路由器是工作在OSI模型**网络层(第3层)**的网络设备,其核心功能是根据数据包中的**目的IP地址**
  • SMUDebugTool:免费开源AMD Ryzen处理器调试工具完整指南
  • 综合算法 XXIX | 网络与算法
  • 如何高效管理Windows右键菜单:个性化定制完整教程
  • 别急着送修!Win10开机提示No Bootable Device?先试试这5个自救方法(含Boot Mode设置)
  • iOS 15+免越狱深度定制完全指南:CowabungaLite让你的iPhone与众不同
  • 提升效率300%的OneNote插件终极指南:160+功能完全解锁笔记生产力