对比我们的服务器配置时,你会发现内存容量有些特别:是 384、576 和 1,152 GB,而不是 256、512 或 1,024。这些数字源于处理器与内存的通信方式,也能让你获得平台所能提供的全部带宽。
内存通道简介
内存通道是处理器内存控制器与所连接内存条之间的一条独立通路。各通道并行工作,因此总带宽大致等于单通道带宽乘以已插内存条的通道数。每根 DDR5 内存条还会把数据通路拆分为两个 32 位子通道,以提升效率,但选型时依据的仍是通道数。
在 DDR5-6000 下,单个通道的理论带宽最高为 48 GB/s:每秒 60 亿次传输(6,000 MT/s),每次 8 字节。放到我们的产品线上,结果如下:
| 平台 | 服务器 | 通道数 | 理论峰值带宽 |
|---|---|---|---|
| AMD EPYC 9005 单路 | Pro、Max 96、GPU RTX PRO | 12 | 576 GB/s |
| AMD EPYC 9005 双路 | Max 192 | 24 | 1,152 GB/s |
| AMD EPYC 4005 | Core、Storage | 2 | 同等内存频率下为单颗 EPYC 9005 的六分之一 |
实际应用能持续达到的带宽低于这些峰值。如果你的工作负载依赖内存带宽,请在服务器上用 STREAM 等工具实测。
每通道一根内存条
我们在每个通道上都只安装一根规格相同的内存条,原因有三。
- 每个通道都贡献带宽。带宽随已插内存条的通道数增长,12 个通道只插了 8 个的处理器,最多只能达到峰值的三分之二。
- 内存均匀交错。所有内存条规格一致时,连续的内存块会分布到所有通道上。混插不同容量或插法不均衡,会让部分内存区域只能在较少的通道间交错,性能也会因数据所在位置而波动。
- 内存全速运行。每通道一根内存条,平台才能以所支持的最高内存频率运行。每通道再加一根,通常会被迫降频。
因此,每路的内存容量都是单根内存条容量的 12 倍:
| 服务器 | 内存条 | 总内存 |
|---|---|---|
| Pro 32 | 12 × 32 GB | 384 GB |
| Pro 48 和 GPU RTX PRO | 12 × 48 GB | 576 GB |
| Pro 64 | 12 × 64 GB | 768 GB |
| Max 96 | 12 × 96 GB | 1,152 GB |
| Max 192 | 24 × 64 GB | 1.5 TB |
48 GB 和 96 GB 内存条采用 24 Gb 内存颗粒,这是 DDR5 才引入的密度规格。它们填补了 2 的幂次容量之间的空档,同时不打破每通道一根内存条的原则。
GPU L40S 配备 256 GB 内存,是为另一类任务设计的:在单 GPU 推理服务器上,模型驻留在 GPU 的 48 GB 显存中,因此主机内存不像在数据库服务器上那么关键。
Core 和 Storage 的双通道
Core 和 Storage 系列采用的 AMD EPYC 4005 处理器有两个内存通道。因此内存带宽远低于 Pro 服务器,换来的是非常高的频率:加速频率最高 5.4 GHz,Core 16X 更是达到 5.7 GHz。Core 16X 还借助 3D V-Cache 拥有 128 MB L3 缓存,能把更多热数据留在离核心更近的地方。
对于游戏服务器、Web 应用和 CI 构建机这类热数据大多能放进缓存的场景,频率比内存带宽更重要,Core 系列的性价比更高。而对于分析扫描、大型内存数据集和高密度虚拟化,12 通道更胜一筹。
带宽与容量的权衡
内存选型要回答两个不同的问题。
容量:工作集放得下吗?放不下,系统就得从 NVMe 读取。NVMe 在存储设备中已经很快,但每次访问需要数微秒,而 DRAM 只需约 100 纳秒,相差两到三个数量级。
带宽:核心能以多快的速度读完这些数据?数据一旦进入内存,分析查询、内存列式存储、大规模排序以及许多 HPC 程序的速度,就取决于内存供数有多快。
按核心数折算,就能看出 EPYC 9005 各型号之间的取舍。表中带宽均为理论峰值。
| 服务器 | 核心数 | 每核内存 | 每核峰值带宽 |
|---|---|---|---|
| Pro 32 | 32 | 12 GB | 18 GB/s |
| Pro 48 | 48 | 12 GB | 12 GB/s |
| Pro 64 | 64 | 12 GB | 9 GB/s |
| Max 96 | 96 | 12 GB | 6 GB/s |
| Max 192 | 192 | 8 GB | 6 GB/s |
Pro 32 的每核带宽最高,适合对带宽要求高、但难以扩展到大量核心的任务。Max 服务器的总容量和总带宽最大,适合能分摊到大量核心、并需要把超大数据集放在内存中的工作负载。
数据库的内存选型
目标是把常用数据和索引放在内存中,并为连接和操作系统留出空间。
- PostgreSQL 同时依赖自身的缓冲区缓存和操作系统的页缓存。常见的起步配置是将
shared_buffers设为内存的 25% 左右,其余留给页缓存。work_mem按每个排序或哈希操作分配,因此大量繁忙的连接会让它的占用成倍增加。 - MySQL(InnoDB)在独占整台服务器时,通常会把 60% 到 75% 的内存分配给
innodb_buffer_pool_size。 - Redis 将全部数据集保存在内存中。请为后台持久化留出余量:后台保存会 fork 出子进程,在写入密集时可能需要大量额外内存。
虚拟机的内存选型
对于生产环境的宿主机,先把所有虚拟机的内存加起来,再为宿主机本身和存储缓存预留内存,例如使用 ZFS 时的 ZFS ARC。内存气球(ballooning)和内存页合并可以提高部署密度,但虚拟化层一旦内存不足,所有虚拟机都会同时变慢。
在双路的 Max 192 上,应尽量让每台虚拟机只使用一颗处理器的核心和内存。Proxmox VE 为每台虚拟机提供了 NUMA 选项来实现这一点;宿主机的配置方法见我们的 Proxmox 指南。
查看服务器的内存布局
在 Linux 上,可以查看每根内存条的容量和配置频率,以及 NUMA 布局:
dmidecode -t memory | grep -E '^\s+(Size|Locator|Configured Memory Speed):'
numactl --hardware在 Pro 或 Max 服务器上,应能看到每路 12 个插槽全部插满,且容量一致。
如需对比配置,请查看 Pro 系列和 Max 系列;平台其他方面的变化,请阅读 EPYC 9005 带来了哪些变化。