溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

KVM虛擬化原理中的塊設(shè)備IO虛擬化是怎樣的

發(fā)布時(shí)間:2021-12-03 17:25:00 來(lái)源:億速云 閱讀:131 作者:柒染 欄目:云計(jì)算

KVM虛擬化原理中的塊設(shè)備IO虛擬化是怎樣的,相信很多沒(méi)有經(jīng)驗(yàn)的人對(duì)此束手無(wú)策,為此本文總結(jié)了問(wèn)題出現(xiàn)的原因和解決方法,通過(guò)這篇文章希望你能解決這個(gè)問(wèn)題。

塊設(shè)備IO虛擬化簡(jiǎn)介

作為另外一個(gè)重要的虛擬化資源,塊設(shè)備IO的虛擬化也是同樣非常重要的。同網(wǎng)絡(luò)IO虛擬化類似,塊設(shè)備IO也有全虛擬化和virtio的虛擬化方式(virtio-blk)。現(xiàn)代塊設(shè)備的工作模式都是基于DMA的方式,所以全虛擬化的方式和網(wǎng)絡(luò)設(shè)備的方式接近,同樣的virtio-blk的虛擬化方式和virtio-net的設(shè)計(jì)方式也是一樣,只是在virtio backend端有差別。

傳統(tǒng)塊設(shè)備架構(gòu)

塊設(shè)備IO協(xié)議棧

KVM虛擬化原理中的塊設(shè)備IO虛擬化是怎樣的

如上圖所示,我們把塊設(shè)備IO的流程也看做一個(gè)TCP/IP協(xié)議棧的話,從最上層說(shuō)起。

Page cache層,這里如果是非直接IO,寫操作如果在內(nèi)存夠用的情況下,都是寫到這一級(jí)后就返回。在IO流程里面,屬于writeback模式。 需要持久化的時(shí)候有兩種選擇,一種是顯示的調(diào)用flush操作,這樣此文件(以文件為單位)的cache就會(huì)同步刷到磁盤,另一種是等待系統(tǒng)自動(dòng)flush。

VFS,也就是我們通常所說(shuō)的虛擬文件系統(tǒng)層,這一層給我們上層提供了統(tǒng)一的系統(tǒng)調(diào)用,我們常用的create,open,read,write,close轉(zhuǎn)化為系統(tǒng)調(diào)用后,都與VFS層交互。VFS不僅為上層系統(tǒng)調(diào)用提供了統(tǒng)一的接口,還組織了文件系統(tǒng)結(jié)構(gòu),定義了文件的數(shù)據(jù)結(jié)構(gòu),比如根據(jù)inode查找dentry并找到對(duì)應(yīng)文件信息,并找到描述一個(gè)文件的數(shù)據(jù)結(jié)構(gòu)struct file。文件其實(shí)是一種對(duì)磁盤中存儲(chǔ)的一堆零散的數(shù)據(jù)的一種描述,在Linux上,一個(gè)文件由一個(gè)inode 表示。inode在系統(tǒng)管理員看來(lái)是每一個(gè)文件的唯一標(biāo)識(shí),在系統(tǒng)里面,inode是一個(gè)結(jié)構(gòu),存儲(chǔ)了關(guān)于這個(gè)文件的大部分信息。這個(gè)數(shù)據(jù)結(jié)構(gòu)有幾個(gè)回調(diào)操作就是提供給不同的文件系統(tǒng)做適配的。下層的文件系統(tǒng)需要實(shí)現(xiàn)file_operation的幾個(gè)接口,做具體的數(shù)據(jù)的讀寫操作等。

struct file_operations {
    //文件讀操作
    ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);
    //文件寫操作
    ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);
    int (*readdir) (struct file *, void *, filldir_t);
    //文件打開操作
    int (*open) (struct inode *, struct file *);
};

再往下就是針對(duì)不同的文件系統(tǒng)層,比如我們的ext3,ext4等等。 我們?cè)赩FS層所說(shuō)的幾個(gè)文件系統(tǒng)需要實(shí)現(xiàn)的接口,都在這一層做真正的實(shí)現(xiàn)。這一層的文件系統(tǒng)并不直接操作文件,而是通過(guò)與下層的通用塊設(shè)備層做交互,為什么要抽象一層通用塊設(shè)備呢?我們的文件系統(tǒng)適用于不同的設(shè)備類型,比如可能是一個(gè)SSD盤又或者是一個(gè)USB設(shè)備,不同的設(shè)備的驅(qū)動(dòng)不一樣,文件系統(tǒng)沒(méi)有必要為每一種不同的設(shè)備做適配,只需要兼容通用快設(shè)備層的接口就可以。

位于文件系統(tǒng)層下面的是通用快設(shè)備層,這一層在程序設(shè)計(jì)里面是屬于接口層,用于屏蔽底層不同的快設(shè)備做的抽象,為上層的文件系統(tǒng)提供統(tǒng)一的接口。

通用快設(shè)備下層就是IO調(diào)度層。用如下命令可以看到系統(tǒng)的IO調(diào)度算法.

?  ~ cat /sys/block/sda/queue/scheduler
noop deadline [cfq]
  1. noop,可以看成是FIFO(先進(jìn)先出隊(duì)列),對(duì)IO做一些簡(jiǎn)單的合并,比如對(duì)同一個(gè)文件的操作做合并,這種算法適合比如SSD磁盤不需要尋道的塊設(shè)備。

  2. cfq,完全公平隊(duì)列。此算法的設(shè)計(jì)是從進(jìn)程級(jí)別來(lái)保證的,就是說(shuō)公平的對(duì)象是每個(gè)進(jìn)程。系統(tǒng)為此算法分配了N個(gè)隊(duì)列用來(lái)保存來(lái)自不同進(jìn)程的請(qǐng)求,當(dāng)進(jìn)程有IO請(qǐng)求的時(shí)候,會(huì)散列到不同的隊(duì)列,散列算法是一致的,同一個(gè)進(jìn)程的請(qǐng)求總是被散列到同一個(gè)隊(duì)列。然后系統(tǒng)根據(jù)時(shí)間片輪訓(xùn)這N個(gè)隊(duì)列的IO請(qǐng)求來(lái)完成實(shí)際磁盤讀寫。

  3. deadline,在Linux的電梯調(diào)度算法的基礎(chǔ)上,增加了兩個(gè)隊(duì)列,用來(lái)處理即將超時(shí)或者超時(shí)的IO請(qǐng)求,這兩個(gè)隊(duì)列的優(yōu)先級(jí)比其他隊(duì)列的優(yōu)先級(jí)較高,所以避免了IO饑餓情況的產(chǎn)生。

塊設(shè)備驅(qū)動(dòng)層就是針對(duì)不同的塊設(shè)備的真實(shí)驅(qū)動(dòng)層了,塊設(shè)備驅(qū)動(dòng)層完成塊設(shè)備的內(nèi)存映射并處理塊設(shè)備的中斷,完成塊設(shè)備的讀寫。

塊設(shè)備就是真實(shí)的存儲(chǔ)設(shè)備,包括SAS,SATA,SSD等等。塊設(shè)備也可能有cache,一般稱為Disk cache,對(duì)于驅(qū)動(dòng)層來(lái)說(shuō),cache的存在是很重要的,比如writeback模式下,驅(qū)動(dòng)層只需要寫入到Disk cache層就可以返回,塊設(shè)備層保證數(shù)據(jù)的持久化以及一致性。
通常帶有Disk cache的塊設(shè)備都有電池管理,當(dāng)?shù)綦姷臅r(shí)候保證cache的內(nèi)容能夠保持一段時(shí)間,下次啟動(dòng)的時(shí)候?qū)ache的內(nèi)容寫入到磁盤中。

塊設(shè)備IO流程

應(yīng)用層的讀寫操作,都是通過(guò)系統(tǒng)調(diào)用read,write完成,由Linux VFS提供的系統(tǒng)調(diào)用接口完成,屏蔽了下層塊設(shè)備的復(fù)雜操作。write操作有直接IO和非直接IO之分(緩沖IO),非直接IO的寫操作直接寫入到page cache后就返回,后續(xù)的數(shù)據(jù)依賴系統(tǒng)的flush操作,如果在flush操作未完成的時(shí)候發(fā)生了系統(tǒng)掉電,那可能會(huì)丟失一部分?jǐn)?shù)據(jù)。直接IO(Direct IO),繞過(guò)了page cache,數(shù)據(jù)必須達(dá)到磁盤后才返回IO操作完成。

對(duì)于I/O的讀寫流程,邏輯比較復(fù)雜,這里以寫流程簡(jiǎn)單描述如下:
KVM虛擬化原理中的塊設(shè)備IO虛擬化是怎樣的

如上圖所示,在初始化IO設(shè)備的時(shí)候,會(huì)為IO設(shè)備分配一部分物理內(nèi)存,這個(gè)物理內(nèi)存可以由CPU的MMU和連接IO總線的IOMMU管理,作為共享內(nèi)存存在。以一個(gè)讀取操作為例子,當(dāng)CPU需要讀取塊設(shè)備的某個(gè)內(nèi)容的時(shí)候,CPU會(huì)通過(guò)中斷告知設(shè)備內(nèi)存地址以及大小和需要讀取的塊設(shè)備地址,然后CPU返回,塊設(shè)備完成實(shí)際的讀取數(shù)據(jù)后,將數(shù)據(jù)寫入到共享的內(nèi)存,并以中斷方式通知CPU IO流程完成,并設(shè)置內(nèi)存地址,接著CPU直接從內(nèi)存中讀取數(shù)據(jù)。
寫請(qǐng)求類似,都是通過(guò)共享內(nèi)存的方式,這樣可以解放CPU,不需要CPU同步等待IO的完成并且不需要CPU做過(guò)多的運(yùn)算操作。
因?yàn)閴K設(shè)備IO的虛擬化需要經(jīng)過(guò)兩次IO協(xié)議棧,一次Guest,一次HV。所以需要把塊設(shè)備IO協(xié)議棧說(shuō)的很具體一點(diǎn)。

至此,Linux塊設(shè)備的IO層就基本介紹完整了,以上內(nèi)容也只是做一個(gè)簡(jiǎn)單的介紹,這部分的內(nèi)容可以很深入的去了解,在此限于篇幅限制,就不做過(guò)多介紹了。

塊設(shè)備IO虛擬化

塊設(shè)備的全虛擬化方式和網(wǎng)絡(luò)IO的DMA設(shè)備虛擬化方式類似,這里就不過(guò)多介紹了,主要介紹一下virtio-blk。

KVM虛擬化原理中的塊設(shè)備IO虛擬化是怎樣的

如上圖所示,藍(lán)色表示 writethrough,黃色表示 none,紅色表示 writeback。其中虛線表示寫到哪一個(gè)層次后write調(diào)用返回。

  • cache=writethrough (藍(lán)色線)
    表示v-backend打開鏡像文件并寫入時(shí)候采用非直接IO+flush操作,也就是說(shuō)每次寫入到Page cache并flush一次,直到數(shù)據(jù)被真實(shí)寫入到磁盤后write調(diào)用返回,這樣必然會(huì)導(dǎo)致數(shù)據(jù)寫入變慢,但是好處就是安全性較高。

  • cache=none (黃色線)
    cache為none模式表示了v-backend寫入文件時(shí)候使用到了DIRECT_IO,將會(huì)繞過(guò)HV的Page cache,直接寫入磁盤,如果磁盤有Disk cache的話,寫入Disk cache就返回,此模式的好處在于保證性能的前提下,也能保證數(shù)據(jù)的安全性,在使用了Disk cache電池的情況下。但是對(duì)于讀操作,因?yàn)闆](méi)有寫入HV Page cache,所以會(huì)有一定性能影響。

  • cache=writeback (紅色線)
    此模式表示v-backend使用了非直接IO,寫入到HV的Page后就返回,有可能會(huì)導(dǎo)致數(shù)據(jù)丟失。

塊設(shè)備IO的虛擬化方式也是統(tǒng)一的virtio-x模式,但是virtio-blk需要經(jīng)過(guò)兩次IO協(xié)議棧,帶來(lái)了不必要的開銷。

看完上述內(nèi)容,你們掌握KVM虛擬化原理中的塊設(shè)備IO虛擬化是怎樣的的方法了嗎?如果還想學(xué)到更多技能或想了解更多相關(guān)內(nèi)容,歡迎關(guān)注億速云行業(yè)資訊頻道,感謝各位的閱讀!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

kvm
AI