一、CPU mode 的选取
本文从性能,热迁移,稳定性,应用移植四个角度对 CPU mode 进行分析。
Libvirt 主要支持三种 CPU mode:
- host-passthrough: libvirt 令 KVM 把宿主机的 CPU 指令集全部透传给 VM 。因此 VM 能够最大限度的使用宿主机 CPU 指令集,故性能是最好的。但是热在迁移时,它要求目的节点的 CPU 和源节点的一致。
- host-model: libvirt 根据当前宿主机 CPU 指令集从配置文件
/usr/share/libvirt/cpu_map.xml
选择一种最相配的 CPU 型号。在这种 mode 下, VM 的指令集往往比宿主机少,性能相对 host-passthrough 要差一点,但是热迁移时,它允许目的节点 CPU 和源节点的存在一定的差异。 - custom: 这种模式下 VM CPU 指令集数最少,故性能相对最差,但是它在热迁移时跨不同型号 CPU 的能力最强。此外,custom 模式下支持用户添加额外的指令集。
1、性能
三种 mode 的性能排序如下:
host-passthrough > host-model > custom
但是它们的差距到底是多少呢,CERN 根据 HEPSpec06 测试标准给出了如下性能数据。
host-passthrough | host-model | custom |
100% | 95.84% | 94.73% |
从上可以总结出:
- 这三种 CPU mode 的性能差距较小
- 除非某些应用对某些特殊指令集有需求,否则不太建议用
host-passthrough,原因请见后续分析。
2、热迁移
从理论上说:
-
host-passthrough
: 要求源节点和目的节点的指令集完全一致 -
host-model
: 允许源节点和目的节点的指令集存在轻微差异 - custom: 允许源节点和目的节点指令集存在较大差异
故热迁移通用性如下:
custom > host-model > host-passthrough
从实际情况来看,公司不同时间采购的 CPU 型号可能不相同;不同业务对 CPU 型号的要求也有差异。虽然常见多采用 intel E5 系列的 CPU,但是该系列的 CPU 也有多种型号,常见的有 Xeon,Haswell,IvyBridge,SandyBridge 等等。即使是 host-model,在这些不同型号的 CPU 之间热迁移 VM 也可能失败。所以从热迁移的角度,在选择 host-mode 时:
- 需要充分考虑既有宿主机类型,以后采购扩容时,也需要考虑相同问题;
- 除非不存在热迁移的场景,否则不应用选择 host-passthrough;
- host-model 下不同型号的 CPU 最好能以 aggregate hosts 划分,在迁移时可以使用 aggregate filter 来匹配相同型号的物理机;
- 如果 CPU 型号过多,且不便用 aggregate hosts 划分,建议使用 「custom mode」;
3、稳定性
从使用经验来看,host-model 和 custom 模式下的 VM 运行稳定,而 host-passthrough
则问题比较大,特别是在 centos6 内核下,常常出现宿主机 kernel panic 问题,如:
- Redhat-6.4_64bit-guest kernel panic with cpu-passthrough and guest numa
所以从稳定性出发:
- 2.6 内核及更早内核版本避免使用
host-passthrough
- 「custom/host-model」 比较稳定
4、应用移植
对应用的影响主要体现在编译型应用,如 C,C++,Golang。在物理机上编译好的二进制应用,直接移植到 custom mode
的 VM 有可能出现 illegal instruction
。其中最常见的 SSE4 类型指令集异常,因为 custom 模式下没有 SSE4 指令集,而在物理机或者其它 mode 的 VM 是有该指令集的。
从经验来看:
- host-model 能够平滑移植绝大部分编译型二进制文件。
- custom 下的 VM 如果出现
illegal instruction
,在该 VM 重新编译(有时需要修改编译参数)应用后,一般能正常运行。 - 如果公司存在大量编译型应用,「host-model」 能让业务上云更平滑些。
VM 网络
重启/etc/init.d/network restart
或者systemctl restart network
五、性能优化
1、CPU优化
kvm 是一个进程,是受 CPU 的调度,对于物理 CPU,同一个 core 的 threads 共享 L2 Cache,同一个 socket 的 cores 共享 L3 cache,所以 VM 的 vcpu 应当尽可能在同一个 core 和 同一个 socket 中,增加 cache 的命中率,从而提高性能。IBM 测试过,合理绑定 vcpu 能给 JVM 来的 16% 的性能提升。
VM vcpu 尽可能限定在一个 core 或者一个 socket 中。例如:当 vcpu 为 2 时,2 个 vcpu 应限定在同一个 core 中,当 vcpu 大于 2 小于 12 时,应限定在同一个 socket 中。
我们可以使用 taskset 来进行操作:
$ taskset -cp 0 8337
pid 8337's current affinity list: 0-3
# 表示当前8337会在0-3CPU上调度
pid 8337's new affinity list: 0
#表示当前8337会在cpu0上进行调度
8377 是进程号,通过 ps -ef|grep kvm 来获取到
-p pid 指定进程
-c 指定cpu(可以写多个)
提示:可以减少开机 miss,性能可以提高10%
2、内存优化
2.1、关闭 KSM
当 Linux 启用了KSM 之后,KSM 会检查多个运行中的进程,并比对它们的内存。如果任何区域或者分页是一样的,KSM 就会毫不犹豫地合并他们成一个分页。那么新分页也是被标记成 copy on write。如果 VM 要修改内存的话,那么 Linux 就会分配新的内存给这个VM。
优点:
- 一个 VM 启动,则只继承了父进程(qemu-kvm)的内存。一台 VM 的内存,可以让相同操作系统或者运行相同应用的 VM共享。
- 当开启了 KSM,常用的进程数据存在缓存和主内存中。这样可以减少 VM 的缓存未命中,同时也提高了 VM 性能。
- 共享内存降低了 VM 的总体内存使用率,从而允许更高的密度和更大的资源利用率。
缺点:
- 利用 KSM 使内存超用。这会导致消耗一定的计算资源用于内存扫描,加重了 CPU 的消耗。内存超用,使得频繁地使用 swap 交互,导致 VM 性能下降。
- KSM使用了边通道(side channels),可能存在泄露客户信息的潜在风险。为此就要考虑在 VM 上关闭 KSM。
所以总结一下应用的场景:
- 生产环境慎用,应急时可开启。
- 测试环境建议使用。
- 桌面虚拟化环境建议使用,但要注意内存使用情况。
关闭 KSM:
1)禁止某个访客与其他访客共享内存,XML文件可配置为:
<memoryBacking>
<nosharepages/>
</memoryBacking>
2)禁止所有访客直接共享内存,主机配置为:
echo 0 > /sys/kernel/mm/ksm/pages_shared
echo 0 > /sys/kernel/mm/ksm/pages_sharing
2.2、打开 huge page
KVM Guest 可以开启大的页内存支持,从而通过增加事务后备缓冲区(TLB)的 CPU 缓存命中率来提高性能。
打开透明大页方式有两种:
- 允许某个 Guest 开启透明大页
<memoryBacking>
<hugepages/>
</memoryBacking>
echo 25000 > /pro c/sys/vm/nr_hugepages
mount -t hugetlbfs hugetlbfs /dev/hugepages
service libvirtd restart
- 允许 Host 中所有 Guest 开启透明大页
echo always > /sys/kernel/mm/transparent_hugepage/enabled
echo never > /sys/kernel/mm/transparent_hugepage/defrag
echo 0 > /sys/kernel/mm/transparent_hugepage/khugepaged/defrag
3、IO 优化
kvm 就使用 virtio。
❝Virtio是一种半虚拟化技术,让磁盘知道你是运行在 VM 里面。这是一种半虚拟化技术,有兴趣可以了解一下。 ❞
3.1、IO cache
kvm 支持多种 VM 多种 IO Cache 方式:writeback, none, writethrough 等。
- 性能上:writeback > none > writethrough
- 安全上:writeback < none < writethrough。
IO cache
权衡安全性和性能,KVM 推荐使用 none:
<disk type='file' device='disk'>
<driver name='qemu' type='qcow2' cache='none'/> # cache 可为 writeback, none, writethrough,directsync,unsafe 等
...
</disk>
3.2、调度算法
Linux kernel 提供了三种 Disk IO 的调度策略,分别为 noop,deadline,cfq。(CentOS 6 有四种)
- noop: noop is often the best choice for memory-backed block devices (e.g. ramdisks) and other non-rotational media (flash) where trying to reschedule I/O is a waste of resources
- deadline: deadline is a lightweight scheduler which tries to put a hard limit on latency
- cfq: cfq tries to maintain system-wide fairness of I/O bandwidth
相关资料:
由于一个宿主机上会运行大量 VM ,为了防止某个因某个 VM 频繁的 IO 操作影响其它 VM ,所以应该选择 cfq 这种公平的调度策略。
查看当前调度算法
$ cat /sys/block/sda/queue/scheduler
noop [deadline] cfq
更改调度算法如下:
echo “noop” > /syc/block/sda/queue/scheduler
3.3、磁盘格式
KVM 常用 Raw 和 Qcow2 格式作为 VM 的镜像文件。对 VM 而言,通俗的说,Raw 格式相当于裸盘,Qcow2 是 copy on write
,二者对比如下:
- 性能:Raw > Qcow2
- 节省空间:Qcow2 > Raw
- 安全:Qcow2 > Raw
Qcow2 格式发展到现在,已经有和 Raw 相近的性能,同时能较好的节省空间,所以推荐使用 「Qcow2」 镜像,但是要最大可能的发挥性能,使用 Raw 格式也未尝不可。
4、网络优化
4.1、启用 vhost_net
VhostNet provides better latency (10% less than e1000 on my system) and greater throughput (8x the normal virtio, around 7~8 Gigabits/sec here) for network.
modprobe vhost-net
4.2、网卡多队列
对 VM 而言,virtio-net 不能并行的处理网络包,当网络流量很大时,单个 vCPU 有限的处理能力将直接影响 VM 的网络流量,所以可以通过多队列的 virtio-net 提高 VM 网络吞吐量。
网卡多队列
<devices>
<interface type='network'>
...
<driver name='vhost' txmode='iothread' ioeventfd='on' event_idx='off' queues='N'/> # queues=N
</interface>
</devices>
vm 查看队列是否生效:
$ ll /sys/class/net/eth0/queues/
总用量 0
drwxr-xr-x 2 root root 0 12月 20 01:24 rx-0
drwxr-xr-x 2 root root 0 12月 20 01:24 rx-1
drwxr-xr-x 2 root root 0 12月 20 01:24 rx-2
drwxr-xr-x 2 root root 0 12月 20 01:24 rx-3
drwxr-xr-x 2 root root 0 12月 20 01:24 rx-4
drwxr-xr-x 2 root root 0 12月 20 01:24 rx-5
drwxr-xr-x 2 root root 0 12月 20 01:24 rx-6
drwxr-xr-x 2 root root 0 12月 20 01:24 rx-7
drwxr-xr-x 3 root root 0 12月 20 01:24 tx-0
drwxr-xr-x 3 root root 0 12月 20 01:24 tx-1
drwxr-xr-x 3 root root 0 12月 20 01:24 tx-2
drwxr-xr-x 3 root root 0 12月 20 01:24 tx-3
drwxr-xr-x 3 root root 0 12月 20 01:24 tx-4
drwxr-xr-x 3 root root 0 12月 20 01:24 tx-5
drwxr-xr-x 3 root root 0 12月 20 01:24 tx-6
drwxr-xr-x 3 root root 0 12月 20 01:24 tx-7
io chache 区别:
1 概览
Cache写机制分为write through和write back两种。
Write-through: Write is done synchronously both to the cache and to the backing store.
Write-back (or Write-behind) : Writing is done only to the cache. A modified cache block is written back to the store, just before it is replaced.
Write-through(直写模式)在数据更新时,同时写入缓存Cache和后端存储。此模式的优点是操作简单;缺点是因为数据修改需要同时写入存储,数据写入速度较慢。
Write-back(回写模式)在数据更新时只写入缓存Cache。只在数据被替换出缓存时,被修改的缓存数据才会被写到后端存储。此模式的优点是数据写入速度快,因为不需要写存储;缺点是一旦更新后的数据未被写入存储时出现系统掉电的情况,数据将无法找回。
3 Write Through和Write Back
Write Through和Write Back是阵列卡Cache的两种使用方式,也称为透写和回写。当选用write through方式时,系统的写磁盘操作并不利用阵列卡的Cache,而是直接与磁盘进行数据的交互。而write Back方式则利用阵列Cache作为系统与磁盘间的二传手,系统先将数据交给Cache,然后再由Cache将数据传给磁盘。在配置阵列的时候,如果不是很清楚的话,默认就可以了,系统会根据磁盘类型进行默认设置。生产环境中的配置要根据具体的业务类型及环境进行配置,比如:如果有外置UPS电源,选Write Back,如果没有外置电源,并且对数据安全性要求很高,不要求太高性能,就选Write Through。
4 Write caching 或 write-through
write-through意思是写操作根本不使用缓存。数据总是直接写入磁盘。关闭写缓存,可释放缓存用于读操作。(缓存被读写操作共用)
Write caching可以提高写操作的性能。数据不是直接被写入磁盘;而是写入缓存。从应用程序的角度看,比等待完成磁盘写入操作要快的多。因此,可以提高写性 能。由控制器将缓存内未写入磁盘的数据写入磁盘。表面上看,Write cache方式比write-through方式的读、写性能都要好,但是也要看磁盘访问方式和磁盘负荷了。
write- back(write cache)方式通常在磁盘负荷较轻时速度更快。负荷重时,每当数据被写入缓存后,就要马上再写入磁盘以释放缓存来保存将要写入的新数据,这时如果数据直 接写入磁盘,控制器会以更快的速度运行。因此,负荷重时,将数据先写入缓存反而会降低吞吐量。
参考:
https://cloud.tencent.com/developer/article/1766168
https://blog.51cto.com/focuslinux/2057792
参考资料:
- [1]:http://wsfdl.com/openstack/2018/01/02/libvirt_cpu_mode.html
- [2]:http://wsfdl.com/openstack/2014/11/17/Nova-KVM%E6%80%A7%E8%83%BD%E8%B0%83%E4%BC%98.html
- [3]:http://www.linux-kvm.org/page/Multiqueue
- [4]:https://i4t.com/1627.html