KVM虚拟化技术详解(四)--KVM的优化
作者:互联网
目录:
(4.1)KVM虚拟机性能优化思路及方案
(4.2)利用tuned优化
(4.3)配置KSM
(4.4)通过配置大页优化guestos
(4.5)配置CPU的亲和性
(4.6)半虚拟化驱动
(4.1)KVM虚拟机性能优化思路及方案
通过前面的学习我们已经可以正常的创建虚拟机了,当然运行虚拟机不是难点,难点在于怎样让我们创建的虚拟机运行的更高效。我们要运行的KVM虚拟机一般要从内存来考虑,考虑每台虚拟机消耗内存的大小;同时还要从CPU资源来考虑,确保每台虚拟机有足够的CPU资源使用,还要保证每台虚拟机使用CPU资源时不会越界而导致系统管理异常;还要从虚拟机的网络消耗来考虑确保网络传输通畅,以及服务在运行时网络的可靠性保证等;最后还要从虚拟机硬盘的IO速率来考虑,保证数据传输时的IO高可靠传输。
(4.2)利用tuned优化
(4.2.1)首先我们检查一下系统中tuned服务是否是正常的运行的。
# yum list tuned*
# systemctl list-unit-files | grep tuned
# systemctl is-active tuned
(4.2.2)tuned服务为我们提供了一系列的优化方案,对系统不同的用途可以采用不同的方案,我们可以使用如下的命令进行查看,其中balanced表示优化负载均衡,desktop表示优化桌面的,network-latency表示优化网络延迟的,network-throughput表示优化网络吞吐量的,powersave表示使用节电模式优化,virtual-guest表示优化客户机的,virtual-host表示优化宿主机的。
# tuned-adm list
(4.2.3)如果我们想知道每个优化方案的具体内容,可以进入到/usr/lib/tuned/目录中查看,可以发现virtual-guest中设置的vm.dirty_ratio值就是/proc/sys/vm/目录下的dirty_ratio
(4.2.4)我们也可以自己定制一个方案kvm-os,在tuned.conf配置文件中修改vm.dirty_ratio值为20
(4.2.5)此时我们发现kvm-os这个方案已经生成了,接着我们设置当前生效的方案为kvm-os,同时发现在我们的系统中/proc/sys/vm/dirty_ratio的值也已经由之前的30变成当前的20了
# tuned-adm list
# tuned-adm profile kvm-os
# cat /proc/sys/vm/dirty_ratio
(4.2.6)我们如果只想查看当前系统使用的方案可以使用active的参数查看,如果我们想查看系统的推荐的优化方案则可以使用recommend参数
# tuned-adm active
# tuned-adm recommend
(4.3)配置KSM
(4.3.1)我们如果从内存方面来考虑优化时,主要会从三个方面入手,分别是balloon、KSM、大页。首先是balloon气球,它主要是通过balloon来实现内存的一种动态收缩,一般如果我们需要修改虚拟机的内存是通过关闭虚拟机后,然后去设置虚拟机的内存大小,正常情况下是无法实现在线修改的,但是我们使用了balloon技术后就可以实现在线修改虚拟机内存大小的需求
(4.3.2)在Linux系统中默认是开启balloon服务的。
# grep -i balloon /boot/config-3.10.0-229.el7.x86_64
(4.3.3)我们在vms002主机上打开KVM环境中的rhel7.1虚拟机,查询到rhel7.1虚拟机的可用内存为2G左右。然后我们可以设置rhel7.1虚拟机的balloon气球的大小为512M,也可以设置rhel7.1虚拟机的balloon气球的大小为1024M,所以可以看出来balloon的数值减小则虚拟机的可用内存减小,balloon的数值增大则虚拟机的可用内存增大。
# virsh --help | grep qemu
# virsh qemu-monitor-command rhel7-1 --hmp --cmd info balloon
# virsh qemu-monitor-command rhel7-1 --hmp --cmd balloon 512
(4.3.4)虽然基于内核的虚拟机KVM被设计为自调优,但是可以调整一些参数使KVM主机性能更好。最重要的参数之一就是内核同页合并KSM(kernel samepage merging),这一特性允许内核更有效地处理内存。KSM允许Linux内核识别出包含相同内容页的内存页,然后合并这些内存页,将数据整合在一个位置可以多次引用。在我们的物理机中如果使用了KSM技术,是可以很好的节约我们的内存空间提升效率的。内存的最小单位是page(页),现在假设我们的物理机上有两台虚拟机,vm1和vm2这两台虚拟机都是会消耗物理机的内存的,所以虚拟机里的内存数据,最终还是保存在物理机的内存中承载的,现在假设vm1和vm2两台虚拟机都各自消耗了1G的内存,此时在物理机中一共消耗2G的内存,此时如果这两个系统是相同的,且运行的服务也是相同的,那么此时vm1的内存中和vm2的内存中应该会存在很多的相同数据,例如有800M的相同数据,那么通过KSM技术便可以将这800M的数据合并在一起共同使用,此时两台虚拟机一共占用的实际物理总内存就会由原来的2048M减少到现在的1248M的空间,这样可以极大的节约我们的物理内存资源。这样就让我们一个物理机4G内存,运行30-50台虚拟机就变成了可能,不过此时还会有其他的问题,例如我们的硬盘可能无法支撑如此多的虚拟机同时运行时的大量IO读写,且我们的CPU如果不够强悍的话可能也是会占用到我们其他服务对CPU资源的使用。
(4.3.5)现在我们在/var/lib/libvirt/images目录中方两个相同的镜像small1.img和small2.img,分别给small1.img和small2.img镜像的内存大小都设置为2048M,并设置好网卡,硬盘,显示协议的配置信息。
注意:我们可以在虚拟机中设置如下的信息,指定虚拟机不使用共享页
# virsh edit small1
<memoryBacking>
<nosharepages/>
</memoryBacking>
(4.3.6)如果我们想要使用KSM技术,则必须要开启ksm.service和ksmtuned.service这两个服务。
# systemctl list-unit-files | grep ksm
(4.3.7)我们进入到/sys/kernel/mm/ksm/目录下,此处的配资文件就是对我们的KSM属性进行设置的。
(4.3.8)/sys/kernel/mm/ksm/目录下run参数一般有3个可用值:0、1、2,其中run值为0代表的是停止相同页扫描,但是已经合并的相同页会继续保留;如果设置的run值为1代表激活相同页合并的扫描;如果设置的run值为2代表的是停止扫描,已经合并的相同页会分开。我们将small1和small2两台虚拟机启动起来后,然后让small1虚拟机和small2虚拟机消耗足够大的内存,将两台虚拟机都挂载到内存中,同时在small1虚拟机上创建一个文件大小为2G,名称为file的文件,并将创建的2G文件拷贝到small2虚拟机上。
# mount -t tmpfs none /mnt
# dd if=/dev/zero of=file bs=1G count=2
# scp file 192.168.122.159:/mnt/
(4.3.9)由于KSM中run的值默认的状态是1,所以是启用相同页合并的功能的,此时我们将run的值修改为2即停止扫描,并将已经合并的相同页分开。可以发现此时两台虚拟机small1和small2所使用的共享内存已经分开了,所以物理机vms002主机消耗由926M增加到了3661M。这就是使用KSM技术给我们内存使用效率带来极大提升的一个表现方式。
# echo 2 > /sys/kernel/mm/ksm/run
(4.3.10)如果我们想要计算使用KSM实际节省了多少的内存,计算正在被合并的page的数量,则可以查看pages_sharing参数,已知系统里page的默认大小值为4096b即4K,所以计算出801794个pages_sharing值为3132M,大约为3G左右的内存空间。
# getconf -a | grep -i page
# echo 801794*4/1024 | bc
(4.3.11)sleep_millisecs表示的是扫描的时间间隔,KSM需要去扫描内存,找到那些相同页,然后把这些相同页合并,因为KSM需要通过扫描操作而找到相同页,但是扫描不可能一直进行,正常的是要有间隔的,所以sleep_millisecs参数就是设置这个间隔参数的,sleep_millisecs参数的默认单位是毫秒,例如在我的主机中cat sleep_millisecs的参数值为41毫秒。每隔41ms扫描一次,扫描的时候,run里的值会被自动设置为1,待扫描完成后,run里的值会自动设置为0。
(4.3.12)pages_unshared表示的是在内存中没有共同数据而无法合并的页;pages_volatile表示的是在内存中有一部分的数据变化非常的频繁,而导致内存是无法合并的;pages_to_scan表示的是从上次休眠到这次休眠之间扫描了多少个页面。
(4.4)通过配置大页优化guestos
配置大页即通过配置page的大小,选择合适的page从而优化我们的虚拟机的运行效率。CPU在执行任务的时候,一次只能执行一个任务,例如CPU在执行一个任务的时候,时间片到期了,那么CPU便会将当前执行的任务封存起来去执行下一个任务,但是对每个任务来说,每个进程都会感觉自己是独享内存的,这个内存叫做线性内存,我们使用ps命令查看的VSZ就是这个线性内存。这个线性内存需要映射到物理内存里,这种映射关系叫做PTE,这个条目被保存在TLB的计算机硬件资源上,其中TLB名为旁路转换缓冲,它是CPU的一个缓存硬件。CPU在进行内存的切换的时候,一般是以页为单位进行切换的,而page页的大小默认是4k,如果某个应用程序消耗大量的内存,此时产生PTE的条目就会很多,切换时就会增加CPU的负载,而我们减缓这个负载的方法就是增大page的单位大小,这样所产生的PTE的条目就会降低,从而使得我们应用程序所运行的环境得到了优化。在我们的x86结构的服务器中,它支持的page的大小有3种:4k、2M(透明大页)、1G,默认的page页大小为4k,当设置的page大小为2M或者1G的时候我们称之为大页或者巨页,当我们运行消耗很大内存的应用程序的时候,我们分配给这个应用程序大页,就可以很好的提高我们读取内存的性能。
(4.4.1)我们通过查看/proc/meminfo就可以了解到当前系统中大页的配置使用情况,当前系统中大页的个数HugePages_Total为0,且大页的默认大小Hugepagesize为2M
# cat /proc/meminfo | grep Huge
(4.4.2)我们也是可以对我们大页的默认值进行设置的,我们进入到/proc/sys/vm/目录下,其中nr_hugepages表示设置大页的数值,我们设置为2500个,所以此时我们系统中一共有2500*2M即5G左右的大页内存空间可用。
(4.4.3)以上的设置只是当前生效,在系统重启后就会失效了,如果我们希望系统在重启后也仍然能够生效,则应该把设置写入到/etc/sysctl.conf的配置文件中
# sysctl -a | grep nr_hugepages >> /etc/sysctl.conf
(4.4.4)接着我们配置一个虚拟机来使用大页,我们编辑rhel7-1虚拟机,添加使用大页的参数,将虚拟机启动后
# virsh edit rhel7-1
<memoryBacking>
<hugepages/>
</memoryBacking>
(4.4.5)此时发现(2500-444)*2M=4112M,约等于4G内存,和我们开启的rhel7-1虚拟机使用的内存一致。这就是我们通过配置大页优化guestos
# grep -i hugepage /boot/config-3.10.0-229.el7.x86_64---查看系统是否支持hugepage 选项
# cat /proc/meminfo | grep Huge
(4.4.6)我们目前使用的大页,系统默认设置的值为2M,我们也可以通过修改配置文件,将默认的大页值修改为1G,hugepagesz=1GB表示设置大页的值为1G,hugepages=5表示设置大页的个数为5个,default_hugepagesz=1GB表示在使用大页时如果没有指定默认是挂载1个大页。然后更新一下内核参数,并将系统重启一下。
# vim /etc/default/grub
# grub2-mkconfig -o /boot/grub2/grub.cfg
(4.4.7)此时我们发现系统中的已经生成了单位大小为1G的大页且有5个,我们将rhel7-1虚拟机启动起来后,便开始使用3个1G的巨页运行虚拟机了,这样便可以有效的提高我们内存和CPU的使用效率。
(4.5)配置CPU的亲和性
(4.5.1)我们的主机是有2颗可用的CPU,所以正常情况下我们的虚拟机的进程是运行在任意的CPU上的。
# ps mo pid,lwp,comm,psr,args pgrep qemu-kvm
(4.5.2)如果我们希望每个虚拟机运行在各自的CPU上,不会互相抢占资源,则可以通过在KVM虚拟机中设置CPU的亲和性,设置rhel7-1虚拟机的进程在1号CPU上运行,设置rhel7-2虚拟机得进程默认是在0号CPU上运行,我们使用top命令查询到两台虚拟机的进程,最终发现两台虚拟机都运行在各自设置的CPU上了。
# virsh edit rhel7-1
(4.6)半虚拟化驱动
在之前的虚拟机P2V迁移过程中,我们的宿主机KVMhost使用的是rhel6.6系统,被迁移的物理机TestRhel7使用的是rhel7.1系统,一般来说我们在做P2V时,就是在被迁移的物理机中,找一张光盘,从光盘引导,然后把这个系统里的数据从本地硬盘迁移到宿主机KVMhost的硬盘里。被迁移的物理机是Linux系统时迁移后是可以正常在宿主机中运行的,但是当被迁移的物理机是Windows系统时却会出现无法正常运行的情况。一般我们把Windows系统安装在物理机上的时候,都会在物理机里安装驱动,这些都是真实的硬件驱动,但是如果被迁移到宿主机的KVM环境里后,例如无法识别KVM环境里的硬盘virtio类型,所以就会导致无法正常开机。所以对Windows系统进行P2V之前,需要先在Windows系统里安装对应的软件包才可以,包括:virtio-win-1.1.16(disk driver).vfd和libguestfs-winsupport-1.0-7.el6.x86_64.rpm。其中virtio-win就是半虚拟化驱动,libguestfs-winsupport就是提供了对NTFS文件系统支持的驱动程序。
(4.6.1)对Windows系统做P2V的过程:1.首先在被迁移的物理机里安装virtio-win和libguestfs-winsuppor驱动程序;2.插入P2V光盘,开始进行P2V迁移;3.在宿主机启动被迁移的虚拟机。
(4.6.2)对Windows系统做V2V的过程:1.首先在Windows虚拟机里安装virtio-win和libguestfs-winsuppor驱动程序;2.把Windows虚拟机的硬盘文件及配置文件拷贝到KVM宿主机里;3.开始对硬盘格式进行转换及配置文件格式转换和文件修改;4.在宿主机启动被迁移的虚拟机。
(4.6.3)接着我们使用一台rhel6.6的系统模拟物理机,在rhel6.6物理机的KVM环境中安装一台Win7系统,用软盘的方式添加virtio-win的驱动
(4.6.4)接着要选择加载驱动程序项,将软盘的Win7加载进来,此时就能正常的看到硬盘分区信息了
(4.6.5)安装好系统后会发现网卡不能识别,这是由于KVM中的Windows虚拟机缺少驱动的原因造成的,此时我们需要将RHEV-toolsSetup_3.5_9.iso这个镜像导入到Windows虚拟机中,首先将CD驱动器弹出,然后设置挂载RHEV-toolsSetup_3.5_9.iso这个镜像,此时找到RHEV-toolsSetup软件运行安装起来即可。
(4.6.6)所有驱动程序安装完毕后需要将系统重启一下,此时我们的系统便正常的获取了IP地址了,同时发现相关的设备也已经安装上了Redhat提供的设备驱动正常运行了。
—————— 本文至此结束,感谢阅读 ——————
标签:大页,虚拟化,虚拟机,KVM,我们,详解,内存,设置,CPU 来源: https://blog.51cto.com/13613726/2460515