记一次虚拟化环境下windowsio性能的解析

朝闻道 朝闻道     2022-09-18     497

关键词:

前言
随着云计算技术与服务的发展和进步,越来越多的客户选择将业务部署到云端。但由于引入了虚拟化层,在业务部署过程中经常会遇到IO问题,通常也不易调试。本文主要介绍利用perf、systemtap等工具,帮助一位托管云客户调试IO性能问题,来分析虚拟环境下Windows IO的性能。

问题出现
有一次,托管云客户自己搭建了虚拟化环境,在同一台宿主机上创建windows 2008 R2 和 Centos6.5虚拟机,用fio分别测试其随机读性能,windows 2008 R2的IOPS大约在18K,而Linux的IOPS却可以达到100K左右。
• 客户测试用的fio 配置
[global]
ioengine=windowsaio
direct=1
iodepth=64
thread=1
size=20g
numjobs=1
[4k]
bs=4k
filename=d:test.img
rw=randread
测试结果

技术分享

win_fio1
• 云主机IO栈

技术分享

io stack
云主机环境下,整个IO栈相对较长,涉及到Guest OS中的应用层/文件系统/Block层以及驱动层,虚拟化层,宿主机OS文件系统/Block层以及驱动层。因为涉及面多,所以其中任何一个环节出现问题都会造成性能下降,也为做IO的Tracing增加了难度。

从这次得到的信息来看,首先排除了宿主机文件系统和Block层以及驱动层的问题,因为同样情况的配置,Linux系统并没有问题。
所以目前主要集中于两点
Guest OS(Windows系统)
fio程序
文件系统/Block layer
VirtIO Block驱动 虚拟机为Guest OS提供的是Virtio Block设备
QEMU

如何排除QEMU的嫌疑?
对于IOPS的性能问题,很容易想到两种可能性:
IO延时过高
设备支持IO队列太短

在队列的问题方面,Linux和Windows虚拟机对应的Virtio Block设备都是一样的,那么就需要确认延时问题。

QEMU 完成Block IO花了多长时间?
幸运的是,Stefan Hajnoczi已经为QEMU添加了Tracing的特性,因此可以很方便的统计出QEMU从接收到一个IO请求到完成所用的具体时长。

技术分享

从上述统计来看,平均IO完成时间在130us,由此暂时排除QEMU 层造成太高延时的影响。另外,如果关注这种动态Tracing的overhead,从测试观察上大致接近20%。
排除队列和延时问题,可能造成影响的也只有Guest OS了。
VirtIO Block驱动的问题?
至少更新到最新稳定版本的Virtio-Win驱动,仍然存在同样的问题。
Windows 文件系统/Block层的问题?
原生Windows系统在确认后并没有做任何配置上的修改。
fio测试程序的问题

为什么Linux上fio没有问题呢?

两种可能性
在性能排查过程中,总是很容易陷入死局,经常会问到底是哪儿出了问题?因此一切可能影响的因素似乎都没有做任何变动。从经验来看,大部分性能问题都可以分成两种可能:
on cpu
off cpu
重新来看这个问题 ,在基本排除IO延时问题后,对应的问题还有两种可能性:
CPU极其忙碌,但是大部分时间并不是在做IO处理;
CPU经常处于空闲状态,那相应的也没有主要在处理IO。
注:之所以说到目前为止并不能排除IO延时的影响,是因为只排除了QEMU Block层可能的影响,但是还有Guest OS(这次暂时忽略Guest OS)。
先看测试过程中,虚拟机的CPU消耗情况。
top -H -p 36256

技术分享

win_fio1
从上图来看,QEMU主线程的cpu负载已经达到90%以上,似乎符合on cpu类问题。通常来说,解决这类问题最好的办法就是用perf进程采样,然后生成火焰图,因为首先查看CPU具体消耗在什么地方是一个不错的选择。
perf record -a -g -p 36256 sleep 20
生成火焰图:

技术分享

win2008-bad
可以清楚的看到,cpu大部分消耗都是KVM的操作,其中最主要的消耗是vmx_handle_exit。(真实的火焰图是一个矢量图,用浏览器查看很容易确认)。这里引起vmx_handle_exit主要有两点:
访问IO Port(handle_pio)
访问 MMIO(handle_apic_access)
既然KVM模块占了大部分,那就更希望了解测试时KVM的真实行为,通过另一个工具(kvm_stat)可以达到。

技术分享

kvm_pio
除VM Entry和VM Exit事件外,最高的就是kvm_pio和 kvm_mmio,说明Windows确实有大量IO Port和MMIO操作,这也验证了在火焰图上所得出的结论。
在虚拟化里,IO Port或者MMIO都可能引起VM Exit,甚至是Heavy Exit。如果需要改善性能,一般都会尽量避免这种情况,至少避免Heavy Exit.

•具体访问哪些IO Port和MMIO导致的VM Exit?

对于这个问题,KVM模块已经加了很多trace event,上面的kvm_stat也是利用这些trace event,只是并没有把具体trace event信息打印出来。为了获取trace-event的信息,有很多前端工具,如trace-cmd、perf,都是不错的选择。
• 查看所有kvm模块的trace event
[[email protected] ]# trace-cmd list -e | grep kvm
kvmmmu:kvm_mmu_pagetable_walk
kvmmmu:kvm_mmu_paging_element
kvmmmu:kvm_mmu_set_accessed_bit
kvmmmu:kvm_mmu_set_dirty_bit
kvmmmu:kvm_mmu_walker_error
kvmmmu:kvm_mmu_get_page
kvmmmu:kvm_mmu_sync_page
kvmmmu:kvm_mmu_unsync_page
kvmmmu:kvm_mmu_zap_page
kvm:kvm_entry
kvm:kvm_hypercall
kvm:kvm_pio
kvm:kvm_cpuid
kvm:kvm_apic
kvm:kvm_exit
kvm:kvm_inj_virq
kvm:kvm_inj_exception
kvm:kvm_page_fault
kvm:kvm_msr
kvm:kvm_cr
kvm:kvm_pic_set_irq
kvm:kvm_apic_ipi
kvm:kvm_apic_accept_irq
kvm:kvm_eoi
kvm:kvm_pv_eoi
kvm:kvm_write_tsc_offset
kvm:kvm_ple_window
kvm:kvm_vcpu_wakeup
kvm:kvm_set_irq
kvm:kvm_ioapic_set_irq
kvm:kvm_ioapic_delayed_eoi_inj
kvm:kvm_msi_set_irq
kvm:kvm_ack_irq
kvm:kvm_mmio
KVM模块添加了许多trace event的点,这里只抓起其中两个——kvm:kvm_pio和kvm:kvm_mmio。

技术分享

trace-cmd-pio-mmio

通过统计发现主要访问的:
IO Port是0x608和0xc050;
MMIO是0xFEE003xx
经由qemu info mtree命令,可以查看IO Port 608、c050以及FEE003xx分别对应的具体设备。
•IO Port
0000000000000608-000000000000060b (prio 0, RW): acpi-tmr 000000000000c040-000000000000c07f (prio 1, RW): virtio-pci
•MMIO
00000000fee00000-00000000feefffff (prio 4096, RW): icc-apic-container
c050可以忽略,这个被Virtio Block来做VM Exit。
到目前为止,可以判断出wnidows大量读取ACPI Power Manager Timer以及访问APIC寄存器,进而导致过多vm exit产生,消耗大量CPU资源,因此就可以具体讨论两个问题:
1.如何减少读取ACPI PM Timer寄存器而引起的VM Exit;
2.如何减少访问APIC MMIO导致的VM Exit。

如何减少读取ACPI PM Timer而引起的VM Exit?
从虚拟化层优化的思路来说,减少IO Port引发的VM Exit通常会考虑是否可以利用Paravirtulization替换Full-virtualization 以达到目的,来看Windows在这方面是如何做的。
从Windows 7开始,微软为了使Windows 操作系统能够在HyperV得到更好性能,特意为Windows系统做了很多虚拟化方面的增强工作,其中就包括这里可以利用到的HyperV Timer,这个特性类似于Linux中的kvmclock。
从当前的支持情况来看:
Windows 7
Windows 7 SP1
Windows Server 2008 R2
Windows Server 2008 R2 SP1/SP2
Windows 8/8.1/10
Windows Server 2012
Windows Server 2012 R2
这些Windows系统都包含虚拟化增强功能,更多的信息在微软官方网站。
2014年,RedHat工程师Vadim Rozenfeld和Peter Krempa 分别为qemu和libvirt添加了HyperV Timer的支持,所以可以直接通过libvirt使能HyperV Timer。

<clock …>

<timer name=’hypervclock’ present=’yes’/>

</clock>

另外,KVM里很早也支持了HyperV Timer,只是客户的宿主机内核版本并不支持该功能,所以需要为客户升级UCloud自己维护的内核版本。
•如何减少APIC ACCESS而引起 VM Exit?
Intel CPU也已经支持apic-v,同样升级到UCloud自己维护的内核版本来解决。
最终效果

技术分享

win-fio-good

技术分享

win-good

总结
从这个案例可以看出,跟物理环境相比,在虚拟化环境下,Windows IO性能较差时,并不一定真正是IO路径出现问题,可能是一些虚拟化性能的问题对IO性能造成了很大影响。

https://my.oschina.net/u/3675312/blog/1529795

记一次gson在不同环境解析时间结果不同的bug定位(代码片段)

1、前因由于领导要求,将生产服务由本地机房搬迁到了华为云,结果搬迁后发现Gson再解析报文的时候抛了异常:2、BUG定位这个异常指的是:Gson无法解析格式为yyyy-MM-ddHH:mm:ss的时间。由于之前在测试环境测过࿰... 查看详情

记一次gson在不同环境解析时间结果不同的bug定位(代码片段)

1、前因由于领导要求,将生产服务由本地机房搬迁到了华为云,结果搬迁后发现Gson再解析报文的时候抛了异常:2、BUG定位这个异常指的是:Gson无法解析格式为yyyy-MM-ddHH:mm:ss的时间。由于之前在测试环境测过࿰... 查看详情

记一次zookeeper集群搭建

虚拟机环境的准备    操作系统使用的debian7.064位,虚拟机软件使用的virtual-box    虚拟机使用的centos6.9无桌面版(本来下载一个7.0发现没有32位的)    centos.iso下载地址:http://mirrors.163.c... 查看详情

unity记一次profiler补捉到的粒子性能优化

关于Profiler优化的一些实践前2天的Profiler连手机Unity记一次Profiler连真机测试优化实践_大话程序员-CSDN博客前2天的Profiler测gcallocUnity记一次Profiler补捉到的gcalloc_大话程序员-CSDN博客f这2天,想顺便做下粒子的优化才发现,原... 查看详情

记一次xlrd读取excel为none的解决

参考技术A需求是这样的,在linux环境下监控一个文件夹中的文件增删情况,发现新的excel文件进行python解析成xml文件后存放于另外的文件夹。在Windows上进行编码测试均OK,但是在linux上进行测试时发现监控脚本发现文件新增后调... 查看详情

记一次gson在不同环境解析时间结果不同的bug定位(代码片段)

1、前因由于领导要求,将生产服务由本地机房搬迁到了华为云,结果搬迁后发现Gson再解析报文的时候抛了异常:2、BUG定位这个异常指的是:Gson无法解析格式为yyyy-MM-ddHH:mm:ss的时间。由于之前在测试环境测过࿰... 查看详情

记一次趋势ds_for_vm_nsx环境的部署(惨痛回忆)

客户虚拟化版本VMware-NSX-Manager-6.3.2-5672532.ovaVMware-VCSA-all-6.5.0-5705665.isoVMware-VMvisor-Installer-201704001-5310538.x86_64.iso 安装DS,在NSX里部署gi和dsva,安装完后都没问题,安装参考文档”DS9.6部署.pptx”最初是客户要求dsva能不能从共 查看详情

记一次初级dvwa爆库

一前期准备1sqlmap在windows环境下需要python2.7的支持,在python官网下载即可https://www.python.org/2安装python2.7,默认即可。安装完成后需要配置下环境变量。右击计算机->高级系统设置->环境变量,找到系统变量的Path选项,双击,在... 查看详情

记一次虚拟机deepin15.11深度操作系统安装

一、基础环境说明1、官方网站https://www.deepin.org/download/2、官方下载https://www.deepin.org/download/3、VMware版本:VMwareWorkstationPro15二、系统安装1、在VMware选择“新建虚拟机”2、自定义安装 deepin15.11虚拟机3、选择虚拟机的安装目录4、... 查看详情

记一次bindissue解决过程(代码片段)

在IBM的大机测试环境下,编辑好的程序已经通过编译,并且拷贝到了RND的目录中。但是用之前能够正常BIND其它DB2程序的JCL去做RND环境下的BIND的时候,总是BIND错误。通过查看JCL的错误信息,定位到如下的SQL错误......SQLCODE=-206SQLSTA... 查看详情

记一次生产环境nginx图片上传不了的问题(代码片段)

在server节点目录下配置:client_max_body_size8M;client_body_buffer_size8M;不过还是不能上传就执行下面这条命令:cd/var/lib/nginx/chmod-R775nginx/  查看详情

记一次前端性能优化的案例

前两天遇到一个前端性能相关的bug,感觉还挺典型的,整理了一下解决过程和思路,写下来分享给大家。场景是这样的,有一个答题的界面,可以播放音频、填空、提交答案,界面是长这个样子的:看起来还挺简单吧,但是我们... 查看详情

记一次定时备份任务的失败原因

备份计划失败原因:使用whichxtrabackup获取xtrabackup的绝对路径,直接调用脚本可以获取,但是在crontab中获取不了,报以下异常#which从环境变量中搜索++whichxtrabackupwhich:noxtrabackupin(/usr/bin:/bin)原因是crontab中环境变量是(/usr/bin:/bin),... 查看详情

记一次idea性能调优

  因自研的自动化测试工具包含压测功能,在自己本地代码开发完毕后进行测试,对目标接口进行1000次访问,发现idea在执行结束后变的异常卡顿,怀疑是idea工具或者程序代码存在问题,遂进行排查。---------------------------------... 查看详情

记一次系统性能优化

用thinkphp3.2.3做了自己的毕业设计,上线使用后发现,响应时间比较长,经过检测后发现是SQL的查询时间太长。这里要感谢系统性能监控平台听云,他们的官网是:http://www.tingyun.com它能检测到不正常的web请求不正常的SQL查询接着... 查看详情

记一次某应用虚拟化系统远程代码执行(代码片段)

...线漏洞团队通过“X漏洞奖励计划”获取到瑞友天翼应用虚拟化系统远程代码执行漏洞情报(0day),攻击者可以通过该漏洞执行任意代码,导致系统被攻击与控制。瑞友天翼应用虚拟化系统是基于服务器计算架构的应用虚拟化平台... 查看详情

记一次clickhouse性能测试

前言在工作场景中,我们会采集工厂设备数据用于智能控制,数据的存储用了InfluxDB,随着数据规模越来越大,InfluxDB的性能越来越差,故考虑引入ClickHouse分担InfluxDB大数据分析的压力,再加上我们业务上... 查看详情

记一次django响应超慢的解决过程

  在本地windows机器开发的Django项目运行正常,放到服务器上后响应超慢,花了一整个工作日没找到原因(非常绝望),又花了一整个周末才找到原因和临时解决办法,如果你的项目超慢可以参考一下解决思路。 排查过程... 查看详情