共計(jì) 4412 個(gè)字符,預(yù)計(jì)需要花費(fèi) 12 分鐘才能閱讀完成。
本篇文章給大家分享的是有關(guān)虛擬化環(huán)境下 Windows IO 性能的解析是怎樣的,丸趣 TV 小編覺得挺實(shí)用的,因此分享給大家學(xué)習(xí),希望大家閱讀完這篇文章后可以有所收獲,話不多說,跟著丸趣 TV 小編一起來看看吧。
前言
隨著云計(jì)算技術(shù)與服務(wù)的發(fā)展和進(jìn)步,越來越多的客戶選擇將業(yè)務(wù)部署到云端。但由于引入了虛擬化層,在業(yè)務(wù)部署過程中經(jīng)常會(huì)遇到 IO 問題,通常也不易調(diào)試。下面主要介紹利用 perf、systemtap 等工具,幫助一位托管云客戶調(diào)試 IO 性能問題,來分析虛擬環(huán)境下 Windows IO 的性能。
問題出現(xiàn)
有一次,托管云客戶自己搭建了虛擬化環(huán)境,在同一臺(tái)宿主機(jī)上創(chuàng)建 windows 2008 R2 和 Centos6.5 虛擬機(jī),用 fio 分別測(cè)試其隨機(jī)讀性能,windows 2008 R2 的 IOPS 大約在 18K,而 Linux 的 IOPS 卻可以達(dá)到 100K 左右。
? 客戶測(cè)試用的 fio 配置
[global]
ioengine=windowsaio
direct=1
iodepth=64
thread=1
size=20g
numjobs=1
[4k]
bs=4k
filename=d:test.img
rw=randread
測(cè)試結(jié)果
win_fio1
? 云主機(jī) IO 棧
io stack
云主機(jī)環(huán)境下,整個(gè) IO 棧相對(duì)較長(zhǎng),涉及到 Guest OS 中的應(yīng)用層 / 文件系統(tǒng) /Block 層以及驅(qū)動(dòng)層,虛擬化層,宿主機(jī) OS 文件系統(tǒng) /Block 層以及驅(qū)動(dòng)層。因?yàn)樯婕懊娑啵云渲腥魏我粋€(gè)環(huán)節(jié)出現(xiàn)問題都會(huì)造成性能下降,也為做 IO 的 Tracing 增加了難度。
從這次得到的信息來看,首先排除了宿主機(jī)文件系統(tǒng)和 Block 層以及驅(qū)動(dòng)層的問題,因?yàn)橥瑯忧闆r的配置,Linux 系統(tǒng)并沒有問題。
所以目前主要集中于兩點(diǎn)
?Guest OS(Windows 系統(tǒng))
?fio 程序
?文件系統(tǒng) /Block layer
?VirtIO Block 驅(qū)動(dòng) 虛擬機(jī)為 Guest OS 提供的是 Virtio Block 設(shè)備
?QEMU
如何排除 QEMU 的嫌疑?
對(duì)于 IOPS 的性能問題,很容易想到兩種可能性:
?IO 延時(shí)過高
?設(shè)備支持 IO 隊(duì)列太短
在隊(duì)列的問題方面,Linux 和 Windows 虛擬機(jī)對(duì)應(yīng)的 Virtio Block 設(shè)備都是一樣的,那么就需要確認(rèn)延時(shí)問題。
QEMU 完成 Block IO 花了多長(zhǎng)時(shí)間?
幸運(yùn)的是,Stefan Hajnoczi 已經(jīng)為 QEMU 添加了 Tracing 的特性,因此可以很方便的統(tǒng)計(jì)出 QEMU 從接收到一個(gè) IO 請(qǐng)求到完成所用的具體時(shí)長(zhǎng)。
從上述統(tǒng)計(jì)來看,平均 IO 完成時(shí)間在 130us,由此暫時(shí)排除 QEMU 層造成太高延時(shí)的影響。另外,如果關(guān)注這種動(dòng)態(tài) Tracing 的 overhead,從測(cè)試觀察上大致接近 20%。
排除隊(duì)列和延時(shí)問題,可能造成影響的也只有 Guest OS 了。
?VirtIO Block 驅(qū)動(dòng)的問題?
至少更新到最新穩(wěn)定版本的 Virtio-Win 驅(qū)動(dòng),仍然存在同樣的問題。
?Windows 文件系統(tǒng) /Block 層的問題?
原生 Windows 系統(tǒng)在確認(rèn)后并沒有做任何配置上的修改。
fio 測(cè)試程序的問題
為什么 Linux 上 fio 沒有問題呢?
兩種可能性
在性能排查過程中,總是很容易陷入死局,經(jīng)常會(huì)問到底是哪兒出了問題?因此一切可能影響的因素似乎都沒有做任何變動(dòng)。從經(jīng)驗(yàn)來看,大部分性能問題都可以分成兩種可能:
?on cpu
?off cpu
重新來看這個(gè)問題,在基本排除 IO 延時(shí)問題后,對(duì)應(yīng)的問題還有兩種可能性:
?CPU 極其忙碌,但是大部分時(shí)間并不是在做 IO 處理;
?CPU 經(jīng)常處于空閑狀態(tài),那相應(yīng)的也沒有主要在處理 IO。
注:之所以說到目前為止并不能排除 IO 延時(shí)的影響,是因?yàn)橹慌懦?QEMU Block 層可能的影響,但是還有 Guest OS(這次暫時(shí)忽略 Guest OS)。
先看測(cè)試過程中,虛擬機(jī)的 CPU 消耗情況。
top -H -p 36256
win_fio1
從上圖來看,QEMU 主線程的 cpu 負(fù)載已經(jīng)達(dá)到 90%以上,似乎符合 on cpu 類問題。通常來說,解決這類問題最好的辦法就是用 perf 進(jìn)程采樣,然后生成火焰圖,因?yàn)槭紫炔榭?CPU 具體消耗在什么地方是一個(gè)不錯(cuò)的選擇。
perf record -a -g -p 36256 sleep 20
生成火焰圖:
win2008-bad
可以清楚的看到,cpu 大部分消耗都是 KVM 的操作,其中最主要的消耗是 vmx_handle_exit。(真實(shí)的火焰圖是一個(gè)矢量圖,用瀏覽器查看很容易確認(rèn))。這里引起 vmx_handle_exit 主要有兩點(diǎn):
?訪問 IO Port(handle_pio)
?訪問 MMIO(handle_apic_access)
既然 KVM 模塊占了大部分,那就更希望了解測(cè)試時(shí) KVM 的真實(shí)行為,通過另一個(gè)工具 (kvm_stat) 可以達(dá)到。
kvm_pio
除 VM Entry 和 VM Exit 事件外,最高的就是 kvm_pio 和 kvm_mmio,說明 Windows 確實(shí)有大量 IO Port 和 MMIO 操作,這也驗(yàn)證了在火焰圖上所得出的結(jié)論。
在虛擬化里,IO Port 或者 MMIO 都可能引起 VM Exit,甚至是 Heavy Exit。如果需要改善性能,一般都會(huì)盡量避免這種情況,至少避免 Heavy Exit.
?具體訪問哪些 IO Port 和 MMIO 導(dǎo)致的 VM Exit?
對(duì)于這個(gè)問題,KVM 模塊已經(jīng)加了很多 trace event,上面的 kvm_stat 也是利用這些 trace event,只是并沒有把具體 trace event 信息打印出來。為了獲取 trace-event 的信息,有很多前端工具,如 trace-cmd、perf,都是不錯(cuò)的選擇。
? 查看所有 kvm 模塊的 trace event
[xs3c@devhost1]# 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 的點(diǎn),這里只抓起其中兩個(gè)——kvm:kvm_pio 和 kvm:kvm_mmio。
trace-cmd-pio-mmio
通過統(tǒng)計(jì)發(fā)現(xiàn)主要訪問的:
?IO Port 是 0x608 和 0xc050;
?MMIO 是 0xFEE003xx
經(jīng)由 qemu info mtree 命令,可以查看 IO Port 608、c050 以及 FEE003xx 分別對(duì)應(yīng)的具體設(shè)備。
?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 可以忽略,這個(gè)被 Virtio Block 來做 VM Exit。
到目前為止,可以判斷出 wnidows 大量讀取 ACPI Power Manager Timer 以及訪問 APIC 寄存器,進(jìn)而導(dǎo)致過多 vm exit 產(chǎn)生,消耗大量 CPU 資源,因此就可以具體討論兩個(gè)問題:
1. 如何減少讀取 ACPI PM Timer 寄存器而引起的 VM Exit;
2. 如何減少訪問 APIC MMIO 導(dǎo)致的 VM Exit。
如何減少讀取 ACPI PM Timer 而引起的 VM Exit?
從虛擬化層優(yōu)化的思路來說,減少 IO Port 引發(fā)的 VM Exit 通常會(huì)考慮是否可以利用 Paravirtulization 替換 Full-virtualization 以達(dá)到目的,來看 Windows 在這方面是如何做的。
從 Windows 7 開始,微軟為了使 Windows 操作系統(tǒng)能夠在 HyperV 得到更好性能,特意為 Windows 系統(tǒng)做了很多虛擬化方面的增強(qiáng)工作,其中就包括這里可以利用到的 HyperV Timer,這個(gè)特性類似于 Linux 中的 kvmclock。
從當(dāng)前的支持情況來看:
?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 系統(tǒng)都包含虛擬化增強(qiáng)功能,更多的信息在微軟官方網(wǎng)站。
2014 年,RedHat 工程師 Vadim Rozenfeld 和 Peter Krempa 分別為 qemu 和 libvirt 添加了 HyperV Timer 的支持,所以可以直接通過 libvirt 使能 HyperV Timer。
clock …
timer name=’hypervclock’present=’yes’/
/clock
另外,KVM 里很早也支持了 HyperV Timer,只是客戶的宿主機(jī)內(nèi)核版本并不支持該功能,所以需要為客戶升級(jí) UCloud 自己維護(hù)的內(nèi)核版本。
?如何減少 APIC ACCESS 而引起 VM Exit?
Intel CPU 也已經(jīng)支持 apic-v,同樣升級(jí)到 UCloud 自己維護(hù)的內(nèi)核版本來解決。
最終效果
win-fio-good
win-good
從這個(gè)案例可以看出,跟物理環(huán)境相比,在虛擬化環(huán)境下,Windows IO 性能較差時(shí),并不一定真正是 IO 路徑出現(xiàn)問題,可能是一些虛擬化性能的問題對(duì) IO 性能造成了很大影響。
以上就是虛擬化環(huán)境下 Windows IO 性能的解析是怎樣的,丸趣 TV 小編相信有部分知識(shí)點(diǎn)可能是我們?nèi)粘9ぷ鲿?huì)見到或用到的。希望你能通過這篇文章學(xué)到更多知識(shí)。更多詳情敬請(qǐng)關(guān)注丸趣 TV 行業(yè)資訊頻道。