凌晨两点的香港荃湾机房,我得在 24 小时内给 120 台 VM 找到“新家”
凌晨两点,我到香港做这次迁移,是因为旧集群撑不住了:CPU 利用率常年 70% 以上,一旦高峰就抖;内存超配比例失控,偶发 swap 抖一下就全盘卡;存储更是“瓶颈中的瓶颈”。甲方给了我一个并不好完的 KPI:同机柜功耗不增加、成本持平或略降、VM 密度至少 +25%,同时保障 99 线延迟不劣化。
我把两杯冻柠茶放在最上层理线架上,拎着贴好编号的 NVMe 托架,心里明白:这活儿的关键在 硬件选型的“组合拳”——CPU 虚拟化指令集(EPT/NPT)能不能把 VM-exit 压下去;内存能超配到什么度不炸;本地 NVMe 用什么形态、怎么做阵列。
这篇文章,就是我把那 24 小时里做过的对比评测、踩过的坑、现场的决策逻辑,一五一十讲出来。数据都在表里,命令都在代码块里,你照着抄也能落地。
场景与目标
目标:在香港机房内,基于 KVM/Libvirt(CentOS 7),完成新一代虚拟化节点选型与落地:
- VM 密度(2 vCPU/4 GiB 小型实例 + 8 vCPU/16 GiB 中型实例的混布)≥ 旧集群 +25%
- 99 线延迟不劣化,CPU 抖动 ≤ 5%,存储 p99 写入延迟 ≤ 1.0 ms
- 单节点软预算不超旧机型 ±10%,同机柜功耗不升
约束:
- 机柜功耗:每 1/3 机柜约 2.3 kW 上限
- 网络:25 GbE 东西向,10 GbE 下兼容;跨境链路不作为主存储(只做备份/迁移)
- 系统栈:CentOS 7.9(原因:对方既有运维体系)、KVM/libvirt、mdadm + XFS
候选硬件清单与配置
CPU/主机三套候选(实测样机)
| 方案 ID | 处理器 | 插槽 | 总核/线程 | 内存 | 内存通道 | 关键指令/特性 | 备注 |
|---|---|---|---|---|---|---|---|
| H1 | Intel Xeon Silver 4314(Ice Lake) | 2P | 32C/64T | 512 GiB(8×64) | 8 ch/CPU | VT-x、EPT、VT-d、AVX-512 | AVX-512 对少量特定工作负载有优势 |
| H2 | Intel Xeon Gold 6248R(Cascade Lake) | 2P | 48C/96T | 512 GiB(12×32) | 6 ch/CPU | VT-x、EPT、VT-d、AVX-512 | 核多、频率稳,传统强项 |
| H3 | AMD EPYC 7543P(Milan) | 1P | 32C/64T | 512 GiB(8×64) | 8 ch | AMD-V、NPT(RVI)、SEV、AVX2 | 单路性价比高,L3 大、内存带宽优 |
说明:我们优先看 EPT(Intel)/NPT(AMD) 的表现;H3 为单路 P 系列,成本与功耗优势明显,适合香港机房这类功耗受限场景。
本地 NVMe 三种形态
| 方案 ID | 盘型与数量 | 阵列 | 目的 | 关键点 |
|---|---|---|---|---|
| S1 | 2× Intel P4510 2 TB(U.2, PCIe 3.1) | RAID1(mdadm) | 注重可靠性 | 带电保护(PLP),QPS 不高但稳 |
| S2 | 4× Samsung PM9A3 1.92 TB(U.2, PCIe 4.0) | RAID10(mdadm) | 混合负载主力 | 吞吐与低延迟兼顾,扩展性好 |
| S3 | 1× Micron 7450 PRO 3.84 TB(U.2, PCIe 4.0) | 单盘 | 成本敏感/轻度 IO | 单盘简单,注意维护窗口 |
软件栈与调优(CentOS 7)
基础安装
内核与 KVM 参数
- BIOS 打开 IOMMU(Intel VT-d / AMD-Vi)、SR-IOV(如需)、NUMA 显示模式
- 大页策略:混部场景THP=always,关键低延迟 VM 用预留 1G hugepages
- KSM:中度超配时开启,控制扫描速率
NVMe 与阵列
典型 VM XML 片段(libvirt)
<cpu mode='host-passthrough' check='none'>
<feature policy='require' name='vmx'/> <!-- Intel:EPT 自动随 vmx -->
<!-- AMD 则换成 svm;NPT 随 svm -->
<topology sockets='1' cores='4' threads='2'/>
</cpu>
<memoryBacking>
<hugepages/>
</memoryBacking>
<driver name='qemu' queues='4' io='native' cache='none'/>
<iothreads>2</iothreads>
<disk type='file' device='disk'>
<driver name='qemu' type='raw' io='native' cache='none' />
<source file='/var/lib/libvirt/images/vm01.img'/>
<target dev='vda' bus='virtio'/>
<discard>unmap</discard>
</disk>
测试方法学
- CPU:
sysbench cpu单核/8 vCPU,perf stat采 kvm:*、cpu-migrations - 内存:
stream带宽、stress-ng --vm+ KSM 扫描对比 - 存储:
fio4k/128k 随机&顺序,QD1/32;p99、p99.9 关注 - 业务端到端:
pgbench(PostgreSQL)、wrk(Nginx 静态/小动态) - 密度:按 SLA(p99 CPU runqueue < 2.0、p99 写入 < 1 ms)堆 VM 到极限
关键命令(节选):
结果一:CPU 虚拟化指令(EPT/NPT)对性能与 VM-exit 的影响
关闭/开启二级页表对比(以 H3/EPYC 为例,NPT=on/off)
| 场景 | NPT | sysbench(8 线程,events/s) | kvm_exits/s(perf) |
p95 CPU 延迟 |
|---|---|---|---|---|
| A | on | 13,640 | 8.1k | 2.3 ms |
| B | off(kvm_amd npt=0) |
9,220(-32%) | 39k(+381%) | 3.7 ms |
结论:在 KVM 下,开启 NPT/EPT 是必须项。大多数混合负载下,关闭二级页表会直接让 VM-exit 飙升、延迟恶化。Intel 的 H1/H2 结论一致。
主机三方案 CPU 汇总
| 指标 | H1(4314×2) | H2(6248R×2) | H3(7543P×1) |
|---|---|---|---|
| 单线程 sysbench(events/s) | 1,480 | 1,350 | 1,400 |
| 8 线程 sysbench(events/s) | 10,820 | 12,540 | 13,640 |
| VM 密度极限(2 vCPU/4 GiB,小型实例) | 52 台 | 78 台 | 84 台 |
| 功耗(节点满载近似,W) | ~520 | ~780 | ~430 |
解读:单核极限 H1 略优(Ice Lake/AVX-512 带来长尾场景优势),多核与密度 H3 领先,功耗也低,适合功耗受限的香港机房。
结果二:内存超配的“安全区间”
测试设置
- 基线:内存不超配(overcommit=1.0×),KSM off
- 轻度超配:1.3×,KSM on(pages_to_scan=5000,sleep_millisecs=20),balloon 打底
- 过度超配:1.6×,KSM on,允许 zswap(仅用于保护,swap 空间保底)
| 场景 | 超配倍数 | KSM | VM p95 CPU steal | 主机 runqueue p95 |
存储 p99 写延迟 |
|---|---|---|---|---|---|
| 基线 | 1.0× | off | 0.7% | 1.2 | 0.68 ms |
| 轻度 | 1.3× | on | 2.8% | 1.4 | 0.72 ms |
| 过度 | 1.6× | on | 6.5% | 2.1 | 1.35 ms(越线) |
建议:这批节点上,内存超配的“安全区间”≈ 1.2~1.35×。超过 1.5× 基本走向不可控。
实践要点:
- 开 KSM 但控制扫描速率,避免 CPU 被“吃干”
- Balloon 只做“守门员”,不要当常态调度器
- 关键 VM 用 1G hugepages,与其他 VM 隔离抖动
结果三:本地 NVMe 形态(S1/S2/S3)对延迟与吞吐的影响
fio 基准(主机空载,直写 RAW,iothreads=2)
| 指标 | S1:P4510×2 RAID1 | S2:PM9A3×4 RAID10 | S3:7450×1 单盘 |
|---|---|---|---|
| 4k 随机读 QD1(IOPS / p99 μs) | 120k / 80 | 230k / 55 | 150k / 70 |
| 4k 随机写 QD1(IOPS / p99 μs) | 52k / 150 | 180k / 65 | 110k / 90 |
| 4k 随机读 QD32(IOPS / p99 μs) | 750k / 420 | 1.6M / 380 | 900k / 410 |
| 128k 顺序读(GB/s) | 3.2 | 11.5 | 6.5 |
| 128k 顺序写(GB/s) | 2.8 | 7.8 | 3.5 |
解读:S2(4 盘 RAID10)是混合负载的“甜点区”,低尾延迟与高带宽兼顾。S1 的可靠性稳,但小写入 IOPS 明显劣势;S3 单盘可做轻负载或成本敏感场景。
结果四:端到端业务压测(混布 VM,Nginx + PostgreSQL)
- 拓扑:每节点 20 台小型(2 vCPU/4 GiB)+ 6 台中型(8 vCPU/16 GiB),磁盘 vda RAW,
io=native,cache=none - 压测 120 分钟取稳态,统计 p99 指标
| 组合 | wrk 吞吐(req/s) | wrk p99(ms) | pgbench TPS | pgbench p99(ms) |
|---|---|---|---|---|
| H1 + S2 | 148,200 | 18.6 | 22,900 | 28.4 |
| H2 + S2 | 158,500 | 17.9 | 25,400 | 26.1 |
| H3 + S2 | 165,300 | 16.8 | 27,100 |
