内容概要 Hyper-V虚机的虚拟CPU(vCPU)合理分配的依据是什么?本文我们将简单介绍Windows Server 如何使用CPU处理多任务,以及我们所关心的yper-V环境中虚拟CPU的分配问题。
盆盆提示 这是黄利军老师的Windows 2016系列文章第二篇,您可以在公众号里回复群集1,阅读第一篇文章。回复群集2,阅读第二篇文章。
开始之前,先看看物理机的CPU如何调度
我该为我的物理服务器分配多少虚拟CPU给虚机才合理,分配比1:1,2:1,听说还可以到8:1?
我的虚拟化CPU分配比达到4:1,会不会引起CPU资源过载?
我只给虚机分配了物理核数一半的虚拟CPU,但是CPU时间一直在70%左右,而另外一台物理机上的虚拟CPU分配达到3:1,但是CPU使用率也才30%左右,这怎么回事?
我们在规划Hyper-V或者其他虚拟化资源的时候,十有八九会为诸如此类的问题抓耳饶腮。
虚拟化和云计算的目标之一是能将计算资源池化,动态为虚机分配CPU资源和其他资源,当一台物理机上运行多个虚机实例时,这种动态使用CPU的效果就更加明显了。
在虚拟化世界里,虚机CPU该如何分配一直是个没有标准答案的问题。今天这篇文章我们将回归本质去了解Hyper-V虚拟化平台如何分配CPU,希望大家对Hyper-V CPU资源规划原则和方法有个初步的认识。
在开始之前,我们先了解CPU是如何处理任务(也即进程),先回看单核CPU的时代CPU是如何处理多个任务的。CPU核使用线程(线程是一系列的CPU指令)处理任务,单核CPU在某一时刻只能开一个线程处理一个任务,如果有更高优先级的任务需要处理时,CPU会暂停当前的线程,然后开另外一个线程处理新的任务。假设我在一段时间T内要处理2个任务:任务a和任务b,任务b比任务a具有更高的优先级。一开始CPU核开线程A处理任务a,在t1时间段处理任务a时,任务b具有更高的优先级,于是任务b中断CPU后,CPU暂停线程A,然后为任务b开线程B,在t2时间段任务b处理完毕,关闭线程B,再继续线程A在时间段t3完成任务a的处理。如果任务b的优先级不比任务a高,则需要线程处理完任务a后再为任务b开线程,在这段过程中我们可以小结出如下几点:
<图1 单线程处理多个任务>
今天的CPU已经具备多核以及超线程技术,所以多个核在某一时刻可以开多个线程去处理多个任务,对于某个核(不启用超线程)来说,其处理机制不变。但是多核多线程环境里,其他高优先级的任务不需要中断被占用的CPU核来为自己开线程,对于同等优先级的任务也无须等待被占用的CPU核处理完当前任务后为自己开线程,而是利用空闲的CPU核为自己开线程,如图2所示。对于多核CPU的每个核来说,处理的机制和单核CPU一样,计算CPU实际使用时间的方法一样,只不过CPU的时间是多个核的时间总和(N核CPU可以将CPU时间这个长方形的宽增加N倍),线程的管理同样由操作系统任务管理器负责。
<图2 多核处理多个任务>
在物理环境中,Windows Server使用以上的机制为任务进程开启、暂停或者关闭线程,Windows Server承担着CPU管理员的角色,负责管理处理任务的线程。而在虚拟化环境中,因为CPU的调度和管理转移到了虚拟化软件层,所以虚拟化软件承担着CPU管理员的管理角色,负责所有分区操作系统里(包含父分区和子分区)线程的管理。进一步看,父分区和子分区的线程都由虚拟化软件的线程调度器一管理,Hyper-V线程调度程序和物理环境中的操作系统任务管理器承担的角色相当。在虚机系统要处理某个任务时,虚拟化层线程调度器为虚机在某一个或者多个逻辑核里启动一个或者多个线程,如图3所示。
<图3 虚拟化平台CPU逻辑核的分配>
如果在调度那一刻有足够的可用的核,那么线程调度器可以随机在某个可用的核里开线程,但是如果当前没有可用的核,那么这个线程将在线程调度器排队等候,直到有空闲的核释放出来,如图4所示。
<图4 线程调度器队列>
需要明确的是,并不是在虚机设置里分配给某台虚机几个虚拟CPU,这几个虚拟CPU在虚机生命周期内就绑定给了这台虚机了,更像是将CPU“租用”给虚机,而且这种“租赁”周期和“租赁”的CPU核都不是确定的。因此为虚机分配的线程运行的逻辑核是动态的,而不会是固定的,比如在t1时刻虚机当前分配了两个线程运行在逻辑核1和5里,由于逻辑核被其他线程中断等原因,在t2时刻这两个线程可能运行在逻辑核可能是2和4里,也就是说,每个逻辑核运行的线程是随机的。线程调度器掌握着逻辑核分配权,在接到虚机任务请求后为虚机线程运行分配逻辑核,但是不由虚机选择运行在哪个逻辑核里。
在了解了CPU核如何处理线程、如何测算CPU时间以及Hyper-V虚拟化平台CPU分配规则后,我们知道CPU时间取决于任务线程的数量、线程繁忙程度、任务处理时间。实际生产环境的应用类型种类繁多,应用进程所使用的线程的数量、线程繁忙程度、任务处理时间都不同。
在物理机上运行低负载应用虚机时,即使虚拟化比较高,比如在一台20核服务器上给20台运行的虚机分配超过40个虚拟CPU(虚拟化比2:1),由于虚机任务的线程少,而且任务处理时间很短,CPU核在一定时间周期内能够依次运行多个虚机的线程,大部分的核只在少部分时间里处理这些应用的进程就足够了,因此我们在物理机的系统里观察到的CPU使用时间往往是图5这种状态。
<图5 低负载虚机CPU使用时间>
在物理机上运行高负载应用虚机时,即使虚拟化比不高,比如在一台20核服务器上给5台运行的虚机分配超过20个虚拟CPU(虚拟化比1:1),由于虚机任务的线程多、线程繁忙,而且任务处理时间较长,CPU核在一定时间周期内能够依次运行不多的虚机线程,需要用到大部分的核以及它们大部分的时间,因此我们在物理机的系统里观察到的CPU使用时间往往是图6这种状态。
<图6 高负载虚机CPU使用时间>
在具备一定数量的虚机,而且虚机运行的应用多元化的时候,应用进程所使用的线程的数量、线程繁忙程度、任务处理时间都是变化而且难以精确测量的指标,所以我们要获得合适的CPU分配比,可以在前期需要根据实际负载进行粗略评估,在后期按照云平台调度接口进行优化或横向扩展。我们在规划的时候可以根据虚拟化平台的用途进行不同的评估: