kvm 虚拟化


一、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>

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 缓存命中率来提高性能。

打开透明大页方式有两种:

  1. 允许某个 Guest 开启透明大页
>
   />
</memoryBacking>
echo 25000 > /pro c/sys/vm/nr_hugepages
mount -t hugetlbfs hugetlbfs /dev/hugepages
service libvirtd restart
  1. 允许 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:

='file' device='disk'>
  ='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

相关资料:

  • http://www.cnblogs.com/zhenjing/archive/2012/06/20/linux_writeback.html
  • http://jackyrong.iteye.com/blog/898938

由于一个宿主机上会运行大量 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 网络吞吐量。

网卡多队列

  >
    <interface type='network'>
      ...
      ='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

相关