KVM 底层性能优化总结

Written on July 13, 2014 View on GitHub

有一段时间没有更新了,因为被派去干了奇怪的事情,加上单位最近有点调整。 本篇从KVM的角度讲述常见的性能槽点,本人非科学研究者,所以实验数据可能都不是很严谨,仅供参考。

处理器

VT技术

虚拟化标配,不开启会感觉到非常慢,无数据参考。

调度算法

暂时没发现不同调度算法会产生怎样的损耗,但是确定的是,两级切换会产生一定的调度损失。在实际试验中,在开启VT技术的情况下,这层损失远远低于0.5%。

缓存

CPU有各自的缓存,当进程在不同CPU直接杂乱切换的情况下,这层损失最高能达到16%,不过一般都不会达到这么极端的数值。 在NUMA构架下,该损失更严重,但主要是内存访问速度的损失。

其他说明

一般来说,绑定NODE(或者CORE)、不过度分配资源,能有效降低CPU不必要的损耗。

内存

地址映射

两级地址映射会带来一定损失,寻址时间的数学的理论损耗为33%。开启SLAT(EPT)功能,能够减少这多余的开销,通常不会产生超过 20% 的冗余寻址损耗(来自RedHat的数据)。当然寻址时间本来就很短,所以通常不会有太大影响。

NUMA

NUMA架构下,Linux的默认调度策略导致内存极易出现碎片问题(因为Linux总是会尝试让闲置的CPU去帮忙执行),这样导致进程的数据被分配到不同的NODE上,对于KVM这种长时间存在的进程,会导致严重的性能下降,虚拟机越多下降越明显。 在实验环境中,发起64台虚拟机的时候,性能为参考值的54.7%。在绑定CORE之后,性能为80.4%。在16台的情况下,数值分别是90.2%、96.1%。在24台的情况下,数值分别是78.2%、92.6%。可见20台左右时,下降明显(测试机器为64内核)。

设备

半虚拟化

半虚拟化(有时也成为超虚拟化)是一个蛮有争议的技术,一方面在当前情况下,半虚拟化能够带来设备的性能提升,减少设备模拟的压力,另一方面半虚拟化降低了虚拟机的灵活性和独立性。

设备的瓶颈

不同设备的模拟瓶颈不一样,如存储设备的瓶颈在宿主机的IO能力,USB设备瓶颈在USB协议本身,而网卡的瓶颈则比较不确定。 半虚拟化对于瓶颈在宿主机的IO的设备上,半虚拟化能够优化IO的行为;对于瓶颈在CPU的设备上,能够大大减少CPU压力。但这仅限于理论,在实际情况下,应该根据实际测试的情况作为参考,根据瓶颈选择最优参数。

关于存储设备

存储设备可谓是虚拟机内性能损耗最明显的设备,原因是多方面的,如虚拟机镜像格式、虚拟机内部文件系统、调度策略。 RAW格式必然是理论性能最佳的格式,但是它会产生一个巨大的文件,仍然会受到碎片因素影响。 目前而言,EXT3是最合适的内部文件系统,EXT4的一些机制与虚拟机本身不匹配。但如果直接使用设备映射,则另当别论。 4种常见调度策略(NOOP、DEADLINE、CFQ、AS)中,CFQ通常是默认策略,但是其不适合虚拟镜像,NOOP和DEADLINE是比较合理的选择,NOOP更适合SSD。 在实际测试中,SSD+NOOP+RAW格式,能够达到90%的宿主机性能。

其他槽点

分配策略

过度分配资源,配合Linux的调度策略,能够使得宿主机的物理资源被充分利用。但于此同时(尤其在虚拟机繁忙的时候),可能会带来明显的损耗。操作系统由于需要保证所有的进程都被适当执行而不断进行资源切换,而带来额外的损耗。在极限情况下,这样的损耗可能会超过 50% 的CPU资源(一般不会超过10%)。过度分配资源也会产生一定的页面交换请求,这本身于EPT技术有一定的冲突,可能会造成交换资源浪费。 保守分配资源,表面上看资源被公平合理的分配出去。实际上,由于各个计算任务压力不均,经常导致一部分资源闲置一部分资源被占满。从数学的角度,资源没有得到充分的利用,但是从性能的角度,没有额外的资源浪费(额外的电能之类)。在此策略下,通常分配 80% 的资源能够保证最佳的性价比,(来自IBM的测试推荐)。分配虚拟机时,按量分配CPU资源, 过度分配资源和保守分配资源分别适合不同的应用场景。

Kernel Same-page Merging

在启用 KSM 的情况下(目前已知使用KSM技术的Hypervisor只有QEMU-KVM),系统定期检测在KSM注册的内存片,寻找相同的片并且合并。 在KVM发起大量相似虚拟机情况下,KSM技术能够极大的减少内存使用,但是也会产生一定量的CPU资源消耗和写回延时(暂时没有数据参考)。 是否开启KSM取决于实际应用场景。

Ballooning

Ballooning技术(需要虚拟机内部驱动支持)能够让虚拟机自动地将长久不用的内存资源上报给宿主机使用。这一定程度上能够实现资源过度分配,减少宿主机压力。 但是在宿主机压力较大的情况下,爆发的虚拟机计算可能会导致内存分配失败,不建议在对稳定性有要求的场合使用。

容器 vs 传统虚拟机

容器技术利用内核本身的资源隔离技术,实现了在隔离环境中运行特定软件的效果。该技术一定程度上符合对计算资源进行分隔共享的效果,由于不需要模拟硬件和运行子操作系统,因此没有额外的模拟代价,资源利用率非常高。 但相比虚拟机,容器并非是一个完整的操作系统,容器之间有着明显的相互影响,并且不能实现用户完全自主控制,因此只适合于特定的计算场景。