精读笔记(RHCA 英文教材)· RH442 Chapter 12 Performing Tuning Hosts in Virtualization Environments
精读笔记(RHCA 英文教材)· RH442 Chapter 12 Performing Tuning Hosts in Virtualization Environments
教材原文:RHCA 官方英文教材(PDF 第 434~475 页)(OCR 整书版已从本站移除,本页为章节精读) 关联中文笔记:
02-09-性能调优RH442(RHCA).md无虚拟化专节(另见02-06-Linux虚拟化等 KVM 基础);本章=虚拟化环境调优两大块:宿主机调优(NUMA/vCPU 绑定/QEMU/内存/KSM/磁盘/网络)→ 虚拟化环境监控(virsh 指标、Prometheus、Grafana)。 结构:2 个 Section(12.1 虚拟化环境宿主机调优+GE virt-host;12.2 虚拟化环境性能监控+GE virt-monitor)+ Lab(lab: virt-review)。
Chapter Goal / Objectives(原文+译)
- GOAL: Distinguish the requirements for tuning in virtualized environments.(区分虚拟化环境下的调优需求。)
- OBJECTIVES: ① 解释虚拟化环境与云环境的宿主机调优差异;② 用开源工具采集虚拟机性能指标。
12.1 Tuning Hosts in Virtualization Environments(宿主机调优)
- 多租户与资源争抢:多台虚拟机共存同一物理机;某台机负载过量(如高峰期做全库备份)会拖垮他人网络/磁盘。宿主上做资源隔离(网络/内存/块 I/O/CPU,宿主与虚机两侧都做)可缓解。
- tuned 档选择:hypervisor 与 guest 各选一档。KVM 宿主推荐 virtual-host(继承 throughput-performance,并把脏页同步阈值从默认 10% 调到系统内存的 5%);guest 用 virtual-guest。
- NUMA 与 CPU 调优:
- 默认开启自动 NUMA balancing(周期解映射内存→产生 NUMA fault 迁移)。手动 NUMA 放置会覆盖自动平衡。
- 建议 guest 内存≤单个 NUMA 节点物理内存量,避免跨节点切分资源;
numastat -c qemu-kvm查 qemu 进程跨节点内存对齐情况。 virsh numatune看内存映射策略:strict 模式下 guest 只能访问指定节点集(numa_nodeset)的内存。- vCPU 绑定:KVM 中 guest vCPU 是宿主的用户态进程;
virsh vcpupin <guest> <vcpu> <hostcpu>绑物理核可提高该进程 CPU 缓存命中率、省内存访问。virsh vcpuinfo查亲和(y- 表示绑到第一个物理 CPU)。XML 由<cputune>定义。 - ⚠️ vCPU 数>物理 CPU 数时必须避免绑定;NUMA 系统上
<vcpupin>与<numatune>必须一起配(NUMA 缓存未命中影响显著)。
- QEMU 模拟器线程:QEMU 多线程跑接近原生速度(主事件循环、异步 I/O 完成、迁移数据传输、SPICE 显示 I/O 等线程)。
virsh emulatorpin rhel8-demo 1把模拟器线程绑到物理 CPU1;XML<cputune><emulatorpin cpuset='1'/></cputune>。 - 宿主内存限额:guest 有两个分配值——最大分配(运行时最多)与当前分配(实际,≤最大)。
virsh dominfo看 Max/Used memory;virsh setmem/setmaxmem改。virsh memtune --hard-limit 2G --soft-limit 1G:hard=物理内存硬上限(设太低可能被内核杀掉 guest),soft=内存争用时强制执行的限额;限额按整体计——要计入 guest 本体+QEMU 线程+guest 显存。virsh memtune输出单位恒为 KiB。XML 用<memtune>。 - 给 guest 分配大页:通过内核引导参数或内存 backing store。XML
<memoryBacking><hugepages><page size='2' unit='M' nodeset='0-3,5'/></hugepages></memoryBacking>;先sysctl -w vm.nr_hugepages=20预留,重启 guest 生效,grep -i huge /proc/meminfo验证。 - KSM(内核同页合并):跑相同 OS/负载的 guest 常有大量相同内存页;KSM 合并相同页为一份、写时 COW 克隆还原,降低总内存占用。需 ksm(扫描合并)与 ksmtuned(控制扫描时机与激进程度)两个服务;手动调
/sys/kernel/mm/ksm/(run、pages_to_scan、sleep_millisecs、pages_shared/sharing、full_scans、merge_across_nodes 等)。virsh node-memory-tune --shm-pages-to-scan 100 --shm-sleep-millisecs 10 --shm-merge-across-nodes 1设参数;ksmtuned 用 /etc/ksmtuned.conf;/etc/sysconfig/ksm的KSM_MAX_KERNEL_PAGES限共享页(缺省/0=最多物理内存一半)。关 KSM:systemctl disable ksm ksmtuned --now;某 guest 单独退出:XML<memoryBacking><nosharepages/></memoryBacking>。共享内存提升性能但降低内存分配灵活性。 - 虚拟磁盘与块 I/O:
- guest 盘优先用块设备(裸盘)而非镜像文件(镜像文件每次 I/O 多一层资源开销)。KVM 两种镜像格式:raw 性能最好;qcow2 开销大(扩容时分配新 cluster 并从 backing file 补数据),特性=稀疏镜像可超量分配宿主存储、COW 存差异不改原盘、快照(Redirect-on-Write,快照只读原盘可写)、zlib 集群压缩、集群加密。
qemu-img create建 qcow2;preallocation 四级:metadata(只预分配元数据,建得快但 guest 写慢)/ falloc(元数据+数据都标好但块未分配,建较快且写更快)/ full(全尺寸分配,建最慢、写性能等同正常盘)。- disk cache 模式(每虚拟盘可配):
cache=none:guest I/O 不缓存到宿主页缓存而走物理盘缓存;通常最佳且支持迁移。cache=writethrough:宿主缓存+写透物理盘,数据落物理盘才算完成——保完整性但写慢。cache=writeback:宿主缓存,写进宿主缓存即算完成,由宿主缓存管理刷盘。cache=directsync:绕宿主缓存直写物理盘(需要时),适合不常发 flush 的 guest。cache=unsafe:类似 writeback 但忽略 guest 所有 flush——不保完整性只增性能,仅适合装系统等场景,生产禁用。- 未指定用宿主默认。XML:
<driver name='qemu' type='qcow2' cache='none' io='native'/>。 - I/O threads(io=native):专用线程替磁盘做块 I/O 提升扩展性;
virsh iothreadinfo/virsh iothreadadd <guest> <id>;XML<iothreads>2</iothreads>+<iothreadids>。建议每个宿主 CPU 最多绑 1~2 个 I/O 线程、每虚拟块设备配一个。io='native'=内核异步 I/O+Direct I/O;不传则用内核默认。 - 块 I/O 限流 QoS:
virsh blkdeviotune rhel8-demo vdb --total-iops-sec 1000 --total-bytes-sec 20M(XML<iotune><total_iops_sec>/<total_bytes_sec>),防止单 guest 吃光物理盘 I/O。 - cgroup 限额:libvirtd 默认为 guest 配 cgroup;
lscgroup见 machine.slice/machine-qemu--.scope(内分 vcpuN、emulator 等)。virsh schedinfo:cpu_shares(默认 1024;2048=两倍 CPU 时间——CPU 份额按宿主所有 guest 权重比分配)、vcpu_period/vcpu_quota、emulator_period/quota、global_period/quota、iothread_period/quota。virsh blkiotune:weight/device_weight(100~1000)给 guest 整体或某设备的块 I/O 相对权重。 - 虚拟网络:宿主内核参数之外,
virtio_net驱动比标准模拟网卡性能好;vhost_net(宿主内核 virtio-net 加速器)系统调用更少,适合 NFV 等关键场景(modinfo vhost_net查看)。SR-IOV:部分 PCIe 网卡把物理 NIC 呈现为多块虚拟 NIC,一个 PF 可被多 guest 共享,打破 1:1 映射——物理功能叫 PF、虚拟功能叫 VF。
12.1 GE(lab: virt-host)
servera(guest rhel8-lab,2 物理 CPU):① virsh list --all 确认 shut off;lscpu|grep -i cpu 看宿主核数;virsh vcpuinfo 看未绑(CPU Affinity: y-y);② 两 vCPU 都绑 CPU0:virsh vcpupin rhel8-lab --config 0 0+--config 1 0(--config 持久化),vcpuinfo/dumpxml 验证(<cputune>);③ 模拟器线程绑 CPU1:virsh emulatorpin rhel8-lab --config 1;④ virsh schedinfo rhel8-lab --config cpu_shares=2048(XML <shares>2048</shares>);⑤ virsh memtune rhel8-lab --config --soft-limit 512MiB(XML <soft_limit unit='KiB'>524288</soft_limit>);systemctl disable ksm ksmtuned --now+virsh edit 加 <memoryBacking><nosharepages/>;⑥ qemu-img create -f qcow2 -o preallocation=metadata /var/lib/libvirt/images/second-disk.qcow2 1G(ls -lh 显示文件系统占用仅 836K、分配 1.1G);virsh edit 挂 vdb:cache='none' io='native';virsh blkdeviotune rhel8-lab vdb --config --total-iops-sec 1000;⑦ virsh domrename rhel8-lab rhel8-lab-tuned→virsh dumpxml > xml→virsh undefine→virsh define xml→virsh start → lab virt-host finish。
12.2 Monitoring Performance Metrics in Virtualization Environment(虚拟化性能监控)
- virsh 直接取指标(按单个 guest 或其设备):
virsh domblkstat rhel8-demo vda --human:读/写操作数、字节、flush 次数及各项耗时(ns)。virsh domiflist查接口(vnet0,virtio),virsh domifstat rhel8-demo vnet0:rx/tx bytes、packets、errs、drop。virsh dommemstat rhel8-demo:actual、swap_in/out、major/minor_fault、unused、available、usable、rss 等。- ⚠️ guest 数量大时不具扩展性,且没有历史数据做趋势分析→用 Prometheus。
- Prometheus(CNCF 毕业项目,源自 SoundCloud):指标型监控(track 系统健康/行为/性能,不追单事件);单实例可处理超百万条时间序列;本地盘存结构化 key-value 时间序列,Go 编写。示例 PromQL:
rate(node_cpu_seconds_total{mode="system"}[1m])。 - 架构要素:服务发现(DNS/Kubernetes/Consul/自定义+配置文件手工加;
http://host:9090/targets列当前目标);scrape 拉取模型(区别于 Graphite 等推模型;抓到的样本按 2 小时一块存成 chunk 文件);PromQL 实时查询(可出图/表格);/metrics端点返回全量指标;Alertmanager 按规则经 SMS/email/chat 告警;Exporter=客户端库/采集器(硬件与内核指标用 node_exporter);Pushgateway:目标在防火墙后无法被拉或生命周期太短时改为推送到 Pushgateway 缓存再被 scrape。 - 部署要点:node_exporter 放每个 target(二进制或 systemd 服务),默认监听 :9100(firewall 放行),浏览器验证
http://host:9100/metrics。Prometheus 解压即用:prometheus.yml(YAML)global(scrape_interval/evaluation_interval)+scrape_configs(job_name+static_configstargets/labels;动态目标用 service discovery/file_sd);./promtool check config prometheus.yml校验;启动./prometheus --storage.tsdb.path /var/lib/prometheus/(默认存当前目录 data/ 子目录,默认保留 15 天)。 - Grafana 可视化:开源,支持 Graphite/InfluxDB/OpenTSDB/Prometheus/Elasticsearch/CloudWatch 数据源;面板+模板变量组成可复用仪表盘;默认
http://localhost:3000(admin/admin 首登)。加 Prometheus 数据源(填 Prometheus 服务器 URL→Save & Test);仪表盘用 JSON 导入(Dashboards→Manage→Import,上传 JSON、选 Prometheus 数据源)。
12.2 GE(lab: virt-monitor)
servera+guest rhel8-lab(192.168.122.12)装 node_exporter(systemd 单元 ExecStart=/usr/lib/node_exporter-0.18.1.linux-amd64/node_exporter,daemon-reload+start+enable;guest 由 servera scp 拷贝二进制与单元;放行 9100);servera 装 Prometheus,prometheus.yml 加两组 job:virt-hosts(servera:9100,label hypervisor)与 virt-guests(192.168.122.12:9100,label virtual-machines);promtool check config 校验;mkdir /var/lib/prometheus+systemd 单元(WorkingDirectory+--storage.tsdb.path);http://servera:9090/targets 全部 Up;workstation yum localinstall grafana-*.rpm+start;http://workstation:3000 admin 登录改密 redhat;加 Prometheus 数据源(servera:9090);导入 node-exporter-full_rev14.json 仪表盘命名 Performance Metrics、刷新 5s、按 Job=virt-hosts/virt-guests 看宿主与 guest 指标 → lab virt-monitor finish。
Lab 概要(lab: virt-review)
serverb:① tuned-adm profile virtual-host;② 模拟器线程绑 CPU0(virsh emulatorpin rhel8-lab --config 0);③ 两个 vCPU 绑 CPU1(virsh vcpupin rhel8-lab --config 0 1+1 1);④ virsh schedinfo --config cpu_shares=2048(两倍于其它 guest 的 1024);⑤ virsh memtune --config --soft-limit 512MiB --hard-limit 1024MiB;⑥ 启 ksm/ksmtuned,virsh node-memory-tune --shm-pages-to-scan 100 --shm-sleep-millisecs 10 --shm-merge-across-nodes 1,cat /sys/kernel/mm/ksm/pages_to_scan、sleep_millisecs、merge_across_nodes 验证;⑦ virsh edit 挂宿主 /dev/vdb1 裸块设备为 vdb(<disk type='block'> driver type='raw' cache='none' io='native'、source dev=/dev/vdb1、target vdb bus=virtio),virsh blkdeviotune rhel8-lab vdb --config --total-iops-sec 1000;⑧ domrename→dumpxml→undefine→define→start 启动 rhel8-lab-tuned → lab virt-review grade、finish。
命令速查表
| 用途 | 命令 | | tuned | tuned-adm profile virtual-host(宿主)/ virtual-guest(虚机) | | NUMA/内存 | numastat -c qemu-kvm;virsh numatune(strict+nodeset) | | vCPU 绑定 | virsh vcpupin <guest> --config <vcpu> <hostcpu>;virsh vcpuinfo | | QEMU 线程 | virsh emulatorpin <guest> --config <cpu> | | 内存限额 | virsh memtune <guest> --config --hard-limit 1024MiB --soft-limit 512MiB;virsh dominfo | | 大页 | sysctl -w vm.nr_hugepages=20;XML memoryBacking/hugepages;grep -i huge /proc/meminfo | | KSM | systemctl enable\|disable ksm ksmtuned --now;virsh node-memory-tune --shm-pages-to-scan 100 --shm-sleep-millisecs 10 --shm-merge-across-nodes 1;/etc/ksmtuned.conf、/etc/sysconfig/ksm | | 镜像 | qemu-img create -f qcow2 -o preallocation=metadata <img> 1G | | I/O 线程 | virsh iothreadinfo\|iothreadadd <guest> 2;XML iothreads/iothreadids;driver io='native' | | 块限流 | virsh blkdeviotune <guest> vdb --config --total-iops-sec 1000 [--total-bytes-sec 20M] | | CPU 份额 | virsh schedinfo <guest> --config cpu_shares=2048 | | 块权重 | virsh blkiotune <guest> --weight 500 [--device-weight vdb,500] | | 取指标 | virsh domblkstat <guest> vda --human;virsh domifstat <guest> vnet0;virsh dommemstat <guest> | | 监控栈 | node_exporter 监听 :9100;./promtool check config prometheus.yml;./prometheus --storage.tsdb.path /var/lib/prometheus/;Grafana :3000 | | 实验/评分 | lab virt-host\|virt-monitor\|virt-review start;lab virt-review grade;… finish |
词汇表
| 英文 | 中文 | 速记 |
|---|---|---|
| multitenancy | 多租户 | 同宿多 guest 共享资源 |
| virtual-host / virtual-guest | tuned 宿主/虚机档 | host 继承 throughput-performance 脏页阈值 5% |
| NUMA balancing / numatune | NUMA 自动平衡/策略 | strict 模式限定节点集 |
| vcpupin / vcpuinfo | vCPU 绑定/查看 | 缓存命中↑;vCPU>物理核时避免绑 |
| emulatorpin | QEMU 线程绑定 | 主循环/异步I/O/迁移/SPICE |
| memtune hard/soft limit | 内存硬/软限 | 整体计含显存;hard 过低会被杀 |
| memory backing / hugepages | 内存后端/大页 | memoryBacking XML 管理 guest 大页 |
| KSM / ksmtuned | 内核同页合并 | 相同页合并+COW;virsh node-memory-tune |
| raw / qcow2 | 裸/写时复制镜像 | raw 快;qcow2 稀疏/快照/压缩/加密 |
| preallocation | 预分配 | metadata/falloc/full |
| cache=none / writeback / unsafe | 磁盘缓存模式 | none 通常最佳可迁移 |
| I/O threads / io=native | I/O 线程/异步直 I/O | 每盘一 I/O 线程;native 配 direct |
| blkdeviotune / iotune | 块 I/O 限流 | total_iops_sec/bytes_sec |
| cpu_shares / schedinfo | CPU 份额 | 2048=两倍 1024 |
| blkiotune weight | 块 I/O 权重 | 100~1000 |
| virtio_net / vhost_net | 半虚拟化网卡 | vhost_net 系统调用更少 |
| SR-IOV / PF / VF | 单根 I/O 虚拟化 | 一 PF 多 VF 共享 |
| domblkstat / domifstat / dommemstat | virsh 取设备指标 | 单机可行、无历史 |
| Prometheus / scrape / PromQL | 监控系统 | 拉模型;2h 块存储;9090 |
| node_exporter / Pushgateway / Alertmanager | 采集器/推网关/告警 | exporter 定义指标 |
| Grafana | 可视化 | 3000 端口;多数据源仪表盘 |
自测 10 题
- virtual-host 档改了什么关键参数?(继承 throughput-performance;脏页同步阈值 10%→5%)
- vCPU 绑定的原理与前提?(vCPU 是宿主用户态进程,绑定提缓存命中;vCPU 数>物理核数时别绑;NUMA 上须与 numatune 同配)
- memtune 的 hard/soft 区别与整体计含义?(hard=硬上限、soft=争用时限额;含 guest+QEMU 线程+显存)
- KSM 何时有用、如何为单 guest 关闭?(相同 OS/负载页重复多;XML nosharepages 或停 ksm/ksmtuned 服务)
- qcow2 相比 raw 的功能与开销?(稀疏/COW/快照/压缩/加密;扩容与额外任务开销)
- cache=none 与 writeback 区别?(none 不缓存宿主页缓存、支持迁移;writeback 写宿主缓存即完成)
- cache=unsafe 何时可用?(仅装机等非生产;忽略 flush 不保完整性)
- virsh 取 guest 指标的三命令?(domblkstat/domifstat/dommemstat;局限=不可扩展、无历史)
- Prometheus 为何用 Pushgateway?(目标被防火墙挡或生命周期太短无法被拉时改推送)
- virt-review 里软硬内存限与 CPU shares 设多少?(soft 512MiB/hard 1024MiB;shares 2048=默认两倍)
