溫馨提示×

溫馨提示×

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

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

如何實現(xiàn)linux塊設(shè)備IO棧淺析

發(fā)布時間:2021-12-18 17:55:46 來源:億速云 閱讀:212 作者:柒染 欄目:云計算

如何實現(xiàn)linux塊設(shè)備IO棧淺析,很多新手對此不是很清楚,為了幫助大家解決這個難題,下面小編將為大家詳細(xì)講解,有這方面需求的人可以來學(xué)習(xí)下,希望你能有所收獲。

linux塊設(shè)備IO棧淺析

塊存儲,簡單來說就是使用塊設(shè)備為系統(tǒng)提供存儲服務(wù)。塊存儲分多種類型,有單機塊存儲,網(wǎng)絡(luò)存儲(如NAS,SAN等),分布式塊存儲(目前主流的如AWS的EBS,青云的云硬盤,阿里云的云磁盤,網(wǎng)易云硬盤等)。通常塊存儲的表現(xiàn)形式就是一塊設(shè)備,用戶看到的就是類似于sda,sdb這樣的邏輯設(shè)備。本文主要介紹Linux塊設(shè)備,對Linux的塊設(shè)備I/O棧進(jìn)行分析。

1.塊設(shè)備基本概念

塊設(shè)備將信息存儲在固定大小的塊中,每個塊都有自己的地址。對操作系統(tǒng)而言,塊設(shè)備是以字符設(shè)備的外觀展現(xiàn)的,例如/dev/sda,雖然對這種字符設(shè)備可以按照字節(jié)為單位訪問,但是實際上到塊設(shè)備上卻是以塊為單位(最小512byte,即一個扇區(qū)),這之間的轉(zhuǎn)換是由操作系統(tǒng)來實現(xiàn)的。
下面介紹幾個塊設(shè)備的基本概念:
1)扇區(qū):磁盤盤片上的扇形區(qū)域,邏輯化數(shù)據(jù),方便管理磁盤空間,是硬件設(shè)備數(shù)據(jù)傳送的基本單位,一般512Byte;
2)塊:塊是VFS和文件系統(tǒng)數(shù)據(jù)傳送的基本單位,必須是扇區(qū)的整數(shù)倍,格式化文件系統(tǒng)時,可以指定塊大?。ㄒ话?12,1024,2048,4096字節(jié));
3)段:一個內(nèi)存頁或者內(nèi)存頁中的一部分,包含一些相鄰磁盤扇區(qū)中的數(shù)據(jù);磁盤的每個I/O操作就是在磁盤與一些RAM單元之間相互傳一些相鄰扇區(qū)的內(nèi)容,大多數(shù)情況下,磁盤控制器采用DMA方式進(jìn)行數(shù)據(jù)傳送。如果不同的段在RAM中相應(yīng)的頁框是連續(xù)的并且在磁盤上相應(yīng)的數(shù)據(jù)塊也是相鄰的,就可以在通用塊層合并它們,產(chǎn)生更大的內(nèi)存區(qū)域,這個區(qū)域稱為物理段。
通常情況下,我們是通過文件系統(tǒng)來訪問塊設(shè)備,也可以直接使用裸設(shè)備,通過指定偏移和大小來讀寫裸設(shè)備。
常見的塊存儲設(shè)備就是物理磁盤,在Linux系統(tǒng)下,還提供基于其他塊設(shè)備之上的邏輯設(shè)備,如Device Mapper,軟RAID等。

2.塊設(shè)備I/O棧

2.1基本概念

介紹塊設(shè)備的I/O棧之前,我們先來了解一下塊I/O棧的幾個基本概念。
1)bio:bio是通用塊層I/O請求的數(shù)據(jù)結(jié)構(gòu),表示上層提交的I/O請求,一個bio包含多個page,這些page必須對應(yīng)磁盤上一段連續(xù)的空間。由于文件在磁盤上并不連續(xù)存放,文件I/O提交到塊設(shè)備之前,極有可能被拆成多個bio結(jié)構(gòu);
2)request:表示塊設(shè)備驅(qū)動層I/O請求,經(jīng)由I/O調(diào)度層轉(zhuǎn)換后的I/O請求,將會發(fā)到塊設(shè)備驅(qū)動層進(jìn)行處理;
3)request_queue: 維護(hù)塊設(shè)備驅(qū)動層I/O請求的隊列,所有的request都插入到該隊列,每個磁盤設(shè)備都只有一個queue(多個分區(qū)也只有一個);
這3個結(jié)構(gòu)的關(guān)系如下圖示:一個request_queue中包含多個request,每個request可能包含多個bio,請求的合并就是根據(jù)各種原則將多個bio加入到同一個requesst中。
如何實現(xiàn)linux塊設(shè)備IO棧淺析

2.2 請求處理方式

io-stack
如圖所示是塊設(shè)備的I/O棧,其中的紅色文字表示關(guān)鍵I/O路徑的函數(shù)。
為了描述I/O處理流程,先介紹一下Direct I/O和緩存I/O的區(qū)別:
1)Direct I/O繞過page cache,而緩存I/O都是寫到page cache里就表示寫請求完成,然后由文件系統(tǒng)的刷臟頁機制把數(shù)據(jù)刷到磁盤。因此,使用緩存I/O,掉電時有可能page cache里的臟數(shù)據(jù)未刷到磁盤上,造成數(shù)據(jù)丟失;
2)緩存I/O機制中,DMA方式可以將數(shù)據(jù)直接從磁盤讀到page cache中,或者將數(shù)據(jù)從page cache直接寫回到磁盤上,而不能直接在應(yīng)用程序地址空間和磁盤之間進(jìn)行數(shù)據(jù)傳輸,這樣的話,數(shù)據(jù)在傳輸過程中需要在應(yīng)用程序地址空間和page cache之間進(jìn)行多次數(shù)據(jù)拷貝操作,這些數(shù)據(jù)拷貝操作所帶來的CPU以及內(nèi)存開銷是非常大的。而Direct I/O的優(yōu)點就是通過減少操作系統(tǒng)內(nèi)核緩沖區(qū)和應(yīng)用程序地址空間的數(shù)據(jù)拷貝次數(shù),降低了對文件讀取和寫入時所帶來的CPU的使用以及內(nèi)存帶寬的占用,但是Direct I/O的讀操作不能從page cache中獲取數(shù)據(jù),會直接從磁盤上讀取,帶來性能上的損失。一般Direct I/O與異步I/O結(jié)合起來使用提高性能。
3)Direct I/O要求用戶態(tài)的緩沖區(qū)對齊;
4)Direct I/O一般用于需要自己管理緩存的應(yīng)用如數(shù)據(jù)庫系統(tǒng)。

對于I/O的讀寫流程,邏輯比較復(fù)雜,這里以寫流程簡單描述如下:
1)用戶調(diào)用系統(tǒng)調(diào)用write寫一個文件,會調(diào)到sys_write函數(shù);
2) 經(jīng)過VFS虛擬文件系統(tǒng)層,調(diào)用vfs_write, 如果是緩存寫方式,則寫入page cache,然后就返回,后續(xù)就是刷臟頁的流程;如果是Direct I/O的方式,就會走到do_blockdev_direct_IO的流程;
3)如果操作的設(shè)備是邏輯設(shè)備如LVM,MDRAID設(shè)備等,會進(jìn)入到對應(yīng)內(nèi)核模塊的處理函數(shù)里進(jìn)行一些處理,否則就直接構(gòu)造bio請求,調(diào)用submit_bio往具體的塊設(shè)備下發(fā)請求,submit_bio函數(shù)通過generic_make_request轉(zhuǎn)發(fā)bio,generic_make_request是一個循環(huán),其通過每個塊設(shè)備下注冊的q->make_request_fn函數(shù)與塊設(shè)備進(jìn)行交互;
4)請求下發(fā)到底層的塊設(shè)備上,調(diào)用塊設(shè)備請求處理函數(shù)__make_request進(jìn)行處理,在這個函數(shù)中就會調(diào)用blk_queue_bio,這個函數(shù)就是合并bio到request中,也就是I/O調(diào)度器的具體實現(xiàn):如果幾個bio要讀寫的區(qū)域是連續(xù)的,就合并到一個request;否則就創(chuàng)建一個新的request,把自己掛到這個request下。合并bio請求也是有限度的,如果合并后的請求超過閾值(在/sys/block/xxx/queue/max_sectors_kb里設(shè)置),就不能再合并成一個request了,而會新分配一個request;
5)接下來的I/O操作就與具體的物理設(shè)備有關(guān)了,交由相應(yīng)的塊設(shè)備驅(qū)動程序進(jìn)行處理,這里以scsi設(shè)備為例說明,queue隊列的處理函數(shù)q->request_fn對應(yīng)的scsi驅(qū)動的就是scsi_request_fn函數(shù),將請求構(gòu)造成scsi指令下發(fā)到scsi設(shè)備進(jìn)行處理,處理完成后就會依次調(diào)用各層的回調(diào)函數(shù)進(jìn)行完成狀態(tài)的一些處理,最后返回給上層用戶。

2.3 request-based和bio-based

在塊設(shè)備的I/O處理流程中,會涉及到兩種不同的處理方式:
1)request-based:這種處理方式下,會進(jìn)行bio合并到request(即I/O調(diào)度合并)的流程,最后才把請求下發(fā)到物理設(shè)備。目前使用的物理盤都是request-based的設(shè)備;
2)bio-based:在邏輯設(shè)備自己定義的request處理函數(shù)make_request_fn里進(jìn)行處理,然后調(diào)用generic_make_request下發(fā)到底層設(shè)備。ramdisk設(shè)備、大部分Device Mapper設(shè)備、virtio-blk都是bio-based;
下圖從Device Mapper的角度來說明request-based和bio-based處理流程的區(qū)別。
一個需要注意的地方是,Device mapper目前只有multipath插件是request-based的,其他的如linear,strip都是bio-based,所以如果是linear DM設(shè)備上創(chuàng)建的一個文件系統(tǒng),對這個文件系統(tǒng)里的文件進(jìn)行讀寫,采用緩存I/O時,即使刷臟頁時是連續(xù)的請求,在DM設(shè)備上也不會進(jìn)行合并,只會到底層的設(shè)備(如/dev/sdb)上才進(jìn)行合并。

看完上述內(nèi)容是否對您有幫助呢?如果還想對相關(guān)知識有進(jìn)一步的了解或閱讀更多相關(guān)文章,請關(guān)注億速云行業(yè)資訊頻道,感謝您對億速云的支持。

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

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

AI