在QEMU/KVM中,qemu提供对cpu的模拟,展现给客户机一定的cpu数目和cpu特性;在KVM打开的情况下,客户机中cpu指令的执行有硬件处理器的虚拟化功能来辅助执行,具有非常高的效率。

  Qemu/kvm为客户机提供一套完整的硬件系统环境,在客户机看来其所拥有的cpu即是vcpu(virtual CPU)。在KVM环境中,每个客户机都是一个标准的Linux进程(qemu进程),而每一个vCPU在宿主机中是Qemu进程派生的一个普通线程。

  在普通的Linux系统中,进程一般有两种执行模式:内核模式和用户模式。在KVM环境中,增加了第三种模式:客户模式。

  • 用户模式(User Mode)

  主要处理I/O的模拟和管理,由Qemu的代码实现。

  • 内核模式(Kernel Mode)

  主要处理特别需要高性能和安全相关的指令,如处理客户模式到内核模式的转换,处理客户模式下的I/O指令或其他特权指令引起的退出(VM-Exit),处理影子内存管理(shadow MMU)。

  • 客户模式(Guest Mode)

  主要执行Guest 中的大部分指令,I/O和一些特权指令除外(他们会引起VM-Exit,被Hypervisor截获并模拟)。


(我们一直强调一个问题)KVM中的一个客户机作为一个用户空间进程(qemu-kvm)运行的,它和其他普通的用户进程一样由内核来调度使其运行在物理cpu上,不过它由KVM模块控制,可以在上面的三种执行模式下运行。

多个客户机就是宿主机中的多个QEMU进程,而一个客户机的多个vCPU就是一个QEMU进程中的多个线程。

在客户机系统中,同样分别运行着客户机的内核和客户机的用户空间应用程序。

  • KVM环境下的SMP

smp,对称多处理器,在虚拟机环境下可以有两种方式实现(个人认为,其实质是一样的)

  1  对于物理硬件非SMP环境,设置虚拟机为smp,多个vcpu在宿主硬件上分时调度。

  2  对于物理硬件为SMP环境,设置虚拟机为smp,多个vcpu在宿主机上被分配到多个cpu上同时执行。

在qemu-kvm的命令中,“-smp”参数即是为了配置客户机的smp系统,

  -smp n[,maxcpus=cpus][,cores=cores][,threads=threads][,sockets=sockets]

  maxcpus最为虚拟机可以使用的vcpu最大值,用于动态添加vcpu,需要虚拟机支持。(在rhel6.5 beta中,测试很完美,加速qemu-ga的guest-set-cpus,可以平滑的将虚拟机的资源做调控)

疑问:

  KVM环境下的smp的架构是如何处理时限的,也就是cores * 2,socket * 2 ,threads * 2与 cores * 1,socket * 8,thread * 1  有什么本质的区别?

  因为为虚拟机提供计算的vcpu在宿主机上实际为一个线程,线程上并不会对cores、sockets或者threads做明确区分,也就是整体设置2*2*2 和 1*8*1是没区别的。

  不过在虚拟机内部,可能会有系统倾向于(服务器的设别程度)多物理插槽,或者多物理核心。(之前遇到的win2k8(非Datacenter)的情况就是,无法识别超过8个的vcpu,但是设置成2*6*1 即可实现12个vcpu的服务器

  • KVM环境下的CPU过载使用

  CPU的过载使用和内存的过载是完全不同的两种用法。CPU是服务器的计算资源,如果没有应用使用cpu,则会被系统idel占用。分配cpu资源的时候也是不会说我给分配20%或30%,而是调整优先级。

  CPU的过载简单的理解就是vcpus的总是大于物理服务器的cpu个数,当虚拟机不是cpu满载的时候,是不会对整体的性能造成影响的。因为我们的系统本身的进程数就远大于cpu的个数,而客户机的进程和普通的进程没有区别,只是有多个vcpu的线程。

!!!强烈不推荐的做法:单台客户机的vcpu总是大于宿主机cpu个数。性能会严重受到影响。

当然,因为服务器上的任何功能都是和cpu关联的,(内存分配、I/O等等),所以我自己不是很推荐虚拟机跑计算密集型的应用或者集中跑密集型的应用(就是大部分的虚拟机都是计算型的)。

  • CPU模型

  每一种VMM(Virtual Machine Monitor)都会定义自己的策略,让客户及看起来有一个默认的CPU模型。(对于cpu的一些特性还是非常模糊,就像模型我还是完全不知道有什么作用)

  有的Hypervisor会简单的将宿主机中的CPU的类型和特性直接传递给客户机使用

  而Qemu/kvm在默认情况下会客户机提供一个名为qemu64和qemu32的基本cpu模型。qemu/kvm的这种策略会带来一些好 处,如可以对cpu特性提供一些高级的过滤功能,还可以将物理平台根据提供的基本cpu模型进行分组。从而让客户机在同一组硬件平台上的动态迁移更加平滑 和安全。(之前有一次就是将虚拟机迁移到另一台机器上,但无法却无法迁移回来,因为缺少cpu指令集)

可以只用qemu-kvm -cpu ?  查看

  • 进程的处理器亲和性和vCPU的绑定

  什么是进程亲和性:简单的一句话就是我这个Linux进程到底可以在哪几个cpu上做负载均衡。

  KVM虚拟机是一个普通的linux进程,vcpu是一个线程,我们可以在宿主机上将vcpu线程对应的tid绑定到指定的cpu上。

  taskset -p [mask] pid

  绑定vcpu到指定的cpu上,的确会提高性能,因为在vcpu的线程在物理cpu做负载均衡的时候,会有一些必要的数据结构初始化 (vmlaunch)相对于VM-Entry来说是比较奢侈的,加上cache的命中,性能必然会有所提高,但破坏了负载均衡。当绑定在同一cpu上的两 个vcpu同时高负载的时候,性能就会大打折扣,而其他的cpu也没有得到充分的利用。

  在KVM环境中,一般并不推荐手动设置qemu进程的处理器亲和性来绑定vCPU,但是,在非常了解系统硬件架构的基础上,根据实际应用的需求,可以将其绑定到特定的CPU上,从而提高客户机中的CPU执行效率或实现CPU资源独享的隔离性。