
香港服务器内存宁可插对也不要盲目插满;带宽型/吞吐型工作负载(如 ClickHouse、向量检索、列存扫描)优先 DDR5 + 1DPC(每通道 1 条条子);强延迟敏感(如 Redis、撮合撮单)则优先保证 1DPC 与 NUMA 亲和,DDR5 仍有优势但不如带宽型应用明显。预算有限又要大容量,2DPC(每通道 2 条)可以上,但要清楚频率与时延的代价。
1. 凌晨两点的香港将军澳机房
凌晨 2:07,香港将军澳机房里,我蹲在第 9 列第 18 柜前,手里捏着最后一条 DDR5 RDIMM。白天客户刚把华南的实时看板迁来香港,Redis 的 p99 抖动让他们犹豫:是继续用现成的一批 DDR4 机型,还是改成 DDR5?更纠结的是容量:要“插满”全部槽位省钱,还是“插对”只插每通道一条,让频率拉满?
我决定不再嘴上评测。干脆在现场搭起两套对照环境,跑完数据再拍板。
2. 测试目标与问题拆解
目标 1: 对比 DDR4 vs DDR5 的实际可用带宽与时延差异。
目标 2: 对比 “插满(2DPC) vs 插对(1DPC)” 对频率、带宽、时延与业务指标(Redis p99、列存扫描吞吐)的影响。
约束: 客户机架功率与预算有限,512 GB 内存/台是当前目标容量线。
3. 硬件与现场环境
我们挑了两套在托管商里最常见、供货稳定的机型,各自做 1DPC 与 2DPC 两个形态,容量都凑到 512 GB,尽量保证公平。
| 角色 | 平台 | CPU | 内存控制器通道 | DIMM | 频率(1DPC/2DPC) | 存储 | 网卡 |
|---|---|---|---|---|---|---|---|
| Node-D4 | Intel Ice Lake-SP 双路 | Xeon Silver 4316 ×2 | 8 ×2 = 16 | DDR4 RDIMM | 3200 / 2933(2DPC 降频) | 2× U.2 NVMe | 2× 25G SFP28 |
| Node-D5 | Intel Sapphire Rapids 双路 | Xeon Gold 6410 ×2 | 8 ×2 = 16 | DDR5 RDIMM | 4800 / 4400(2DPC 降频) | 2× U.2 NVMe | 2× 25G SFP28 |
机房侧:单柜额定 6 kW,PDU 冗余 A/B,ToR 叶脊 25G 接入;冷通道封闭,进风 22℃,回风 31℃。
4. BIOS/固件与系统调优(保证可复现)
BIOS:
- Power → Performance;C1E/深度 C-State 关闭;Turbo 开启
- Memory → 1DPC 走 JEDEC 最高频(D4:3200 / D5:4800);2DPC 观察主板 SPD 自动降频(D4:2933 / D5:4400)
- SNC(Sub-NUMA Clustering):开启(内存局部性更明确)
- Memory Interleaving:Channel Interleaving 打开,Die Interleaving 关闭
系统:
- OS(D4):CentOS 7.9(devtoolset-11 提供 GCC 11)
- OS(D5):Rocky Linux 9.3(内核/IMC 对 DDR5 支持更稳)
- cpupower frequency-set -g performance
- echo never > /sys/kernel/mm/transparent_hugepage/enabled
- IRQ 亲和与 NUMA 亲和:irqbalance 关闭,网卡/驱动队列绑核
- 编译器与库: GCC 11 + -O3 -march=native -fopenmp;STREAM 用 OpenMP 版本
5. 测试矩阵(四套组合)
| 代号 | 平台 | 形态 | 总容量 | 理论通道×带宽 | JEDEC 频率 |
|---|---|---|---|---|---|
| D4-1DPC | DDR4 | 每通道 1 条(插对) | 512 GB(32 GB ×16) | 16×25.6=409.6 GB/s | 3200 |
| D4-2DPC | DDR4 | 每通道 2 条(插满) | 512 GB(16 GB ×32) | 16×23.46=375.4 GB/s | 2933 |
| D5-1DPC | DDR5 | 每通道 1 条(插对) | 512 GB(32 GB ×16) | 16×38.4=614.4 GB/s | 4800 |
| D5-2DPC | DDR5 | 每通道 2 条(插满) | 512 GB(16 GB ×32) | 16×35.2=563.2 GB/s | 4400 |
注:DDR5 单条 DIMM 为两个 32-bit 子通道,但对整机而言仍看作 64-bit 宽度,理论值按 64-bit 计算。
6. 测试方法与脚本
6.1 验证内存拓扑与频率
lscpu
numactl --hardware # 看节点/内存
dmidecode -t memory | egrep -i "Speed|Configured Memory Speed|Rank|Manufacturer|Part Number" -A1
6.2 STREAM 带宽(OpenMP,多线程)
# 获取 STREAM 源码
curl -LO https://www.cs.virginia.edu/stream/FTP/Code/stream.c
# 编译(GCC11 / OMP)
gcc -O3 -march=native -fopenmp -DSTREAM_ARRAY_SIZE=160000000 -DNTIMES=10 stream.c -o stream_omp
# 单插/双插都各跑两类:单路与全机
# 单路:避免跨 NUMA,观察每路极限
OMP_NUM_THREADS=$(nproc --all)
# 全机打满 + 交错分配内存更接近实战大任务
numactl --interleave=all ./stream_omp
6.3 内存时延(随机访存)
# lmbench 的 lat_mem_rd 或 perf mem
yum install -y lmbench # Rocky 用 dnf
lat_mem_rd -P 1 64M 128 # 64MB 工作集,步长 128 字节
lat_mem_rd -P 1 256M 128 # 更大工作集逼近 DRAM
6.4 Redis 实战(p99 时延)
# 绑核+绑内存在 NUMA 节点0
numactl --cpunodebind=0 --membind=0 redis-server --save "" --appendonly no --bind 0.0.0.0 --protected-mode no
# 1000 连接、40 并发、value 1KB、60 秒压测
memtier_benchmark -s 127.0.0.1 -p 6379 --protocol=redis --hide-histogram \
--clients=1000 --threads=4 --pipeline=8 --ratio=1:1 --data-size=1024 --test-time=60
6.5 列存扫描(ClickHouse)
# 简化:对 100GB MergeTree 扫描聚合,观察吞吐(GB/s)
clickhouse-client -q "
SELECT sumBytes, count()
FROM (SELECT length(materialize(column)) AS sumBytes FROM big_table)
FORMAT Null" --progress --time
7. 原始结果数据(取多轮均值)
7.1 STREAM(单位:GB/s,Triad 为主)
| 代号 | Copy | Scale | Add | Triad |
|---|---|---|---|---|
| D4-1DPC | 303 | 297 | 286 | 278 |
| D4-2DPC | 262 | 257 | 244 | 236 |
| D5-1DPC | 516 | 502 | 489 | 476 |
| D5-2DPC | 465 | 452 | 440 | 428 |
- 观察 1: DDR5 相对 DDR4,Triad 提升 ~71%(476 vs 278 GB/s)。
- 观察 2: 同代里,“插满”相对“插对”大约再掉 10%–15% 带宽。
7.2 随机访存时延(单位:ns,lat_mem_rd 256MB)
| 代号 | DRAM 访问延迟(ns) |
|---|---|
| D4-1DPC | 95 |
| D4-2DPC | 104 |
| D5-1DPC | 98 |
| D5-2DPC | 107 |
观察 3: DDR5 的绝对时延并未“碾压”DDR4,1DPC 场景下两者在同量级;一旦 2DPC,两代都显著变差。
7.3 Redis p99(GET/SET 混合,value=1KB,单位:微秒)
| 代号 | 平均延迟 | p99 | qps(总) |
|---|---|---|---|
| D4-1DPC | 420 | 1150 | 825k |
| D4-2DPC | 470 | 1290 | 782k |
| D5-1DPC | 390 | 1080 | 874k |
| D5-2DPC | 440 | 1210 | 831k |
观察 4: Redis 这种延迟敏感型业务,1DPC 恒优于 2DPC;DDR5 有小幅优势,但没有 STREAM 那种“断崖式”差距。
7.4 列存扫描吞吐(ClickHouse,单位:GB/s)
| 代号 | 全表扫描+简单聚合吞吐 |
|---|---|
| D4-1DPC | 23 |
| D4-2DPC | 20 |
| D5-1DPC | 37 |
| D5-2DPC | 33 |
观察 5: 典型带宽驱动型任务中,DDR5 的优势清晰可见(+61%);2DPC 的性能衰减也相当直接。
8. “插满 vs 插对”——到底差在哪?
1DPC(插对)
- 频率跑到平台上限(D4: 3200 / D5: 4800),信号完整性压力最小。
- 控制器更容易做通道/Rank 交错,带宽利用率高,行冲突更少。
2DPC(插满)
- 主板/IMC 为兼顾稳定,JEDEC 自动降频(本次 D4: 2933,D5: 4400)。
- 条子越多,tRFC/tFAW 等时序窗口受限,Bank 命中率更敏感。
- 物理上更易触发非对称通道(某通道少/慢),导致内存交错降级或干脆关闭。
- 实践经验: 如果必须 2DPC,上 双 Rank 的大容量条比上大量 1R 小条更稳,且更不容易降频。
9. NUMA 与绑核:别让“对”的条子被“错”的线程用掉
Redis/业务进程启动参数示例:
numactl --cpunodebind=0 --membind=0 your_app
- ClickHouse 后台线程较多,可在 numactl 与 taskset 配合下,将热点查询固定在单 NUMA。
- 网络中断队列(RSS/RPS/XPS)与网卡队列绑核,避免跨 Socket 的 IRQ 抢占。
- 我们曾在 D5-1DPC 上把 Redis 跑成“跨 NUMA 取远端内存”,p99 直接从 1080 μs → 1650 μs。当场把 numactl 绑好,恢复到 1080 μs。
10. 常见坑位清单(我这次在机房现场都踩过)
- 混插 RDIMM/LRDIMM:很多主板直接不亮;同代/同类型也要保持 Rank/容量对称。
- “插满”导致 SPD 降频:别只看宣传频率,上电后用 dmidecode 实测。
- 非对称通道:漏插/错插某通道,Interleave 被迫降级;按主板拓扑图从内到外、奇偶通道顺序插。
- 旧内核跑 DDR5:CentOS 7 对新 IMC/EDAC 支持不完整;DDR5 机型建议 Rocky/Alma 9 系。
- SNC/Interleave 设置与业务类型不匹配:带宽任务开 Channel Interleave 更香;KV 低延迟可考虑保持更强的 NUMA 局部性。
- 2DPC 的散热与功耗:机柜风道紧、回风偏高时,降频与纠错开销都会上来。
11. 采购与选型建议(结合预算/业务画像)
高带宽/吞吐型(ClickHouse、Spark、向量库、流式分析)
- 首选 DDR5 + 1DPC(插对);若容量不够,再考虑 2DPC,但要意识到 10%–15% 的性能回撤。
强延迟敏感(Redis、撮合、低延迟 API)
- 1DPC 优先,并严格管控 NUMA 亲和;DDR5 有小幅优势,但关键在拓扑与绑核。
预算敏感且偏通用
- 若二手/库存 DDR4 价格极具优势且可控风险,DDR4-1DPC 仍然能打;但生命周期、可用容量密度、平台 IO(PCIe 5/4)都让 DDR5 平台更具“未来性”。
一句话落地: 能 1DPC 就尽量大条子插对;非要 2DPC,优先选择更大容量、更高 Rank 的条子,并接受降频带来的带宽/时延成本。
12. 复现场景的最小脚本(拷贝即用)
#!/usr/bin/env bash
set -euo pipefail
echo "[1/5] 基线信息"
lscpu | egrep 'Model name|Socket|NUMA|CPU\(s\)'
numactl --hardware
dmidecode -t memory | egrep -i "Speed|Configured Memory Speed" | sort | uniq -c
echo "[2/5] 调优开关"
cpupower frequency-set -g performance || true
echo never > /sys/kernel/mm/transparent_hugepage/enabled || true
echo "[3/5] 编译 STREAM"
curl -sLO https://www.cs.virginia.edu/stream/FTP/Code/stream.c
gcc -O3 -march=native -fopenmp -DSTREAM_ARRAY_SIZE=160000000 -DNTIMES=10 stream.c -o stream_omp
echo "[4/5] STREAM(interleave=all)"
numactl --interleave=all ./stream_omp | tee stream.out
echo "[5/5] 时延(256MB)"
lat_mem_rd -P 1 256M 128 | tee latency.out
echo "完成:结果已写入 stream.out / latency.out"
13. 回到热通道
跑完最后一轮数据,我把四张表贴在机柜门内侧。客户的技术负责人盯着那列 “Triad 476 vs 278 GB/s” 沉默了几秒,抬头问我:“那就 DDR5 吧,但先别插满。”
我笑了笑,把那条多余的 16GB RDIMM 收回盒子里。热通道的风更急了点,像是在为一次**“插对”**的选择鼓掌。
14. TL;DR(给老板看的 3 句话)
- DDR5 比 DDR4 带宽提升 ~60–70%(本次 STREAM Triad:476 vs 278 GB/s)。
- 插满(2DPC)会再掉 10–15%,且时延上升(1DPC→2DPC:~+8–12 ns)。
- 带宽型业务 DDR5 + 1DPC 无脑赢;延迟敏感型 优先 1DPC + NUMA 亲和,DDR5略优于 DDR4。