記一次虛擬化環境下Windows IO效能的解析

來源:互聯網
上載者:User

標籤:pagetable   glob   問題:   分析   訪問   fse   統計   增強   hive   

前言
隨著雲端運算技術與服務的發展和進步,越來越多的客戶選擇將業務部署到雲端。但由於引入了虛擬化層,在業務部署過程中經常會遇到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效能造成了很大影響。

原文地址:http://blog.ucloud.cn/archives/2409https://my.oschina.net/u/3675312/blog/1529795

記一次虛擬化環境下Windows IO效能的解析

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.