1. 程式人生 > >虛擬機器儲存IO的那點事

虛擬機器儲存IO的那點事

隨機IO vs 順序IO

一般90%以上的虛擬機器都是隨機IO模型,使用者互動類應用,如桌面,Web,它們的儲存IO在Hypervisor看來都是隨機的,這主要是因為我們常見的檔案格式如jpg, png, exe, elf一般都採用了元資料+資料的模式,應用程式經常需要來回移動檔案指標讀寫檔案中不同的部分,現代多核心多工的作業系統會導致更多這樣的併發任務,進一步加強了這種隨機性。

順序IO模型的典型應用比較少,據我目前所知,大資料應用是其中之一,比如hdfs一般都以很大的block size以資料流的方式讀寫大檔案。

讀快取 vs 寫快取

隨機io會導致更多的cache miss,在此情況下,讀快取(write through)不僅不會帶來任何效能加速,反而還會導致額外的記憶體複製和上下文切換。

從可靠性的角度看,虛擬化一般不會採用寫快取(write back)。如果使用寫快取,在虛擬機器中返回成功的寫請求其實僅僅只是存在hypervisor的記憶體中,一旦主機重啟或者掉電,這部分資料就會丟失。除非使用者能保證他們的虛擬機器可以承受資料丟失,否則我們儘量避免使用write back。

同步IO和非同步IO

同步IO使用read/write呼叫,這些呼叫是阻塞的,為了保障主程序不被阻塞,以及能獲得更大的IO吞吐,通常會使用多個IO執行緒。非同步IO一般使用io_submit核心呼叫,它是非阻塞的,可以在一個執行緒內通過提交更多的IO,有利於IO合併演算法,同時,對於IO密集應用,非同步IO會節省更多的執行緒上下文切換開銷,另外,io_submit會強制使用O_DIRECT的透寫引數繞過快取,所以能更好的適應隨機IO模型,下面兩幅圖對比了同步IO和非同步IO的系統處理流程:

同步IO讀寫流程

非同步IO讀寫流程

KVM虛擬機器的IO執行緒

幾年前還是機械硬碟時代,單盤的容量雖然每年都能翻一番,但是讀寫效能特別是隨機讀寫效能卻是十年如一日,即使是15k轉速的SAS磁碟,單盤僅僅100-200 IOPS,如今的NVME磁碟,隨機讀效能到100k-200k IOPS都不算個事。較早版本的QEMU(KVM的裝置模擬程式)只有一個IO執行緒,這對於早期處理只有數百IOPS的虛擬機器已經足夠了,但是對於數十萬IOPS的新介質,即使把一個CPU完全跑滿,也處理不過來,因此,QEMU社群花了好幾年的時間,歷經好多版本,終於能夠讓IO處理能夠完全脫離主執行緒,跑在多個不同的執行緒裡面,充分利用現代多核處理器的能力,這個特性最早叫做dataplane,現在好像也叫iothread。

虛擬機器配置

虛擬機器磁碟sda配置

disk type='block':這個磁碟的後端是一個塊裝置,可以用lvcreate命令建立;這個引數也可以用type='file', 說明後端是一個檔案,但是在生產環境中,邏輯卷的可靠性一般要高於檔案系統,所以我更喜歡用block。

driver type='qcow2':KVM的磁碟格式預設為QCOW2, 我們一般從作業系統廠商下載的雲映象的格式也都是這個格式,它最大的好處是可以支援磁碟瘦分配(thin provisioning)。

driver cache=’none':使用無快取模式(O_DIRECT)開啟檔案,這個引數還支援writethrough和writeback,對於隨機IO 應用,建議使用none, 對於順序IO應用,可以使用writethrough。

driver io='native':設定native,QEMU會呼叫非同步io_submit來提交IO; 設定為threads,QEMU會最終呼叫pread/pwrite同步提交IO。

iothreads配置

iothreads:指定用4個獨立的執行緒處理磁碟IO。

iothreadpin:將指定的iothread繫結到指定的cpu上執行。

https://segmentfault.com/a/1190000005981794