1. 程式人生 > >最全面的I/O優化介紹 從檔案系統到磁碟管理

最全面的I/O優化介紹 從檔案系統到磁碟管理



1、系統學習

IO效能對於一個系統的影響是至關重要的。一個系統經過多項優化以後,瓶頸往往落在資料庫;而資料庫經過多種優化以後,瓶頸最終會落到IO。而IO效能的發展,明顯落後於CPU的發展。Memchached也好,NoSql也好,這些流行技術的背後都在直接或者間接地迴避IO瓶頸,從而提高系統性能。

IO系統的分層:

  1.   三層結構

上圖層次比較多,但總的就是三部分。磁碟(儲存)、VM(卷管理)和檔案系統。專有名詞不好理解,打個比方說:磁碟就相當於一塊待用的空地;LVM相當於空地上的圍牆(把空地劃分成多個部分);檔案系統則相當於每塊空地上建的樓房(決定了有多少房間、房屋編號如何,能容納多少人住);而房子裡面住的人,則相當於系統裡面存的資料。

  • 檔案系統—資料如何存放?

對應了上圖的File System和Buffer Cache。

File System(檔案系統):解決了空間管理的問題,即:資料如何存放、讀取。

Buffer Cache:解決資料緩衝的問題。對讀,進行cache,即:快取經常要用到的資料;對寫,進行buffer,緩衝一定資料以後,一次性進行寫入。

  • VM—磁碟空間不足了怎麼辦?

對應上圖的Vol Mgmt。

VM其實跟IO沒有必然聯絡。他是處於檔案系統和磁碟(儲存)中間的一層。VM遮蔽了底層磁碟對上層檔案系統的影響。當沒有VM的時候,檔案系統直接使用儲存上的地址空間,因此檔案系統直接受限於物理硬碟,這時如果發生磁碟空間不足的情況,對應用而言將是一場噩夢,不得不新增硬碟,然後重新進行資料複製。而VM則可以實現動態擴充套件,而對檔案系統沒有影響。另外,VM也可以把多個磁碟合併成一個磁碟,對檔案系統呈現統一的地址空間,這個特性的殺傷力不言而喻。

  • 儲存—資料放在哪兒?如何訪問?如何提高IO速度?

對應上圖的Device Driver、IO Channel和Disk Device

資料最終會放在這裡,因此,效率、資料安全、容災是這裡需要考慮的問題。而提高儲存的效能,則可以直接提高物理IO的效能

    2. Logical IO vs Physical IO

邏輯IO是作業系統發起的IO,這個資料可能會放在磁碟上,也可能會放在記憶體(檔案系統的Cache)裡。

物理IO是裝置驅動發起的IO,這個資料最終會落在磁碟上。

      邏輯IO和物理IO不是一一對應的。

這部分的東西在網路程式設計經常能看到,不過在所有IO處理中都是類似的。

IO請求的兩個階段

       等待資源階段:IO請求一般需要請求特殊的資源(如磁碟、RAM、檔案),當資源被上一個使用者使用沒有被釋放時,IO請求就會被阻塞,直到能夠使用這個資源。

       使用資源階段:真正進行資料接收和發生。

舉例說就是排隊服務。

等待資料階段,IO分為阻塞IO和非阻塞IO。

       阻塞IO:資源不可用時,IO請求一直阻塞,直到反饋結果(有資料或超時)。

       非阻塞IO:資源不可用時,IO請求離開返回,返回資料標識資源不可用

使用資源階段,IO分為同步IO和非同步IO。

       同步IO:應用阻塞在傳送或接收資料的狀態,直到資料成功傳輸或返回失敗。

       非同步IO:應用傳送或接收資料後立刻返回,資料寫入OS快取,由OS完成資料傳送或接收,並返回成功或失敗的資訊給應用。

按照Unix的5個IO模型劃分

  • 阻塞IO
  • 非阻塞IO
  • IO複用
  • 訊號驅動的IO
  • 非同步IO

從效能上看,非同步IO的效能無疑是最好的。

各種IO的特點

  • 阻塞IO:使用簡單,但隨之而來的問題就是會形成阻塞,需要獨立執行緒配合,而這些執行緒在大多數時候都是沒有進行運算的。Java的BIO使用這種方式,問題帶來的問題很明顯,一個Socket需要一個獨立的執行緒,因此,會造成執行緒膨脹。
  • 非阻塞IO:採用輪詢方式,不會形成執行緒的阻塞。Java的NIO使用這種方式,對比BIO的優勢很明顯,可以使用一個執行緒進行所有Socket的監聽(select)。大大減少了執行緒數。
  • 同步IO:同步IO保證一個IO操作結束之後才會返回,因此同步IO效率會低一些,但是對應用來說,程式設計方式會簡單。Java的BIO和NIO都是使用這種方式進行資料處理。
  • 非同步IO:由於非同步IO請求只是寫入了快取,從快取到硬碟是否成功不可知,因此非同步IO相當於把一個IO拆成了兩部分,一是發起請求,二是獲取處理結果。因此,對應用來說增加了複雜性。但是非同步IO的效能是所有很好的,而且非同步的思想貫穿了IT系統放放面面。

最重要的三個指標

IOPS

IOPS,即每秒鐘處理的IO請求數量。IOPS是隨機訪問型別業務(OLTP)很重要的一個參考指標。

  • 一塊物理硬碟能提供多少IOPS?

從磁碟上進行資料讀取時,比較重要的幾個時間是:定址時間(找到資料塊的起始位置),旋轉時間(等待磁碟旋轉到資料塊的起始位置),傳輸時間(讀取資料的時間和返回的時間)。其中定址時間是固定的(磁頭定位到資料的儲存的扇區即可),旋轉時間受磁碟轉速的影響,傳輸時間受資料量大小的影響和介面型別的影響(不用硬碟介面速度不同),但是在隨機訪問類業務中,他的時間也很少。因此,在硬碟介面相同的情況下,IOPS主要受限於定址時間和傳輸時間。以一個15K的硬碟為例,定址時間固定為4ms,傳輸時間為60s/15000*1/2=2ms,忽略傳輸時間。1000ms/6ms=167個IOPS。

  • OS的一次IO請求對應物理硬碟一個IO嗎?

在沒有檔案系統、沒有VM(卷管理)、沒有RAID、沒有儲存裝置的情況下,這個答案還是成立的。但是當這麼多中間層加進去以後,這個答案就不是這樣了。物理硬碟提供的IO是有限的,也是整個IO系統存在瓶頸的最大根源。所以,如果一塊硬碟不能提供,那麼多塊在一起並行處理,這不就行了嗎?確實是這樣的。可以看到,越是高階的儲存裝置的cache越大,硬碟越多,一方面通過cache非同步處理IO,另一方面通過盤數增加,儘可能把一個OS的IO分佈到不同硬碟上,從而提高效能。檔案系統則是在cache上會影響,而VM則可能是一個IO分佈到多個不同裝置上(Striping)。

所以,一個OS的IO在經過多箇中間層以後,發生在物理磁碟上的IO是不確定的。可能是一對一個,也可能一個對應多個

  • IOPS能算出來嗎?

對單塊磁碟的IOPS的計算沒有沒問題,但是當系統後面接的是一個儲存系統時、考慮不同讀寫比例,IOPS則很難計算,而需要根據實際情況進行測試。主要的因素有:  

    • 儲存系統本身有自己的快取。快取大小直接影響IOPS,理論上說,快取越大能cache的東西越多,在cache命中率保持的情況下,IOPS會越高。
    • RAID級別。不同的RAID級別影響了物理IO的效率。
    • 讀寫混合比例。對讀操作,一般只要cache能足夠大,可以大大減少物理IO,而都在cache中進行;對寫操作,不論cache有多大,最終的寫還是會落到磁碟上。因此,100%寫的IOPS要越獄小於100%的讀的IOPS。同時,100%寫的IOPS大致等同於儲存裝置能提供的物理的IOPS。
    • 一次IO請求資料量的多少。一次讀寫1KB和一次讀寫1MB,顯而易見,結果是完全不同的。

當時上面N多因素混合在一起以後,IOPS的值就變得撲朔迷離了。所以,一般需要通過實際應用的測試才能獲得。 

IO Response Time

即IO的響應時間。IO響應時間是從作業系統核心發出一個IO請求到接收到IO響應的時間。因此,IO Response time除了包括磁盤獲取資料的時間,還包括了作業系統以及在儲存系統內部IO等待的時間。一般看,隨IOPS增加,因為IO出現等待,IO響應時間也會隨之增加。對一個OLTP系統,10ms以內的響應時間,是比較合理的。下面是一些IO效能示例:

  • 一個8K的IO會比一個64K的IO速度快,因為資料讀取的少些。
  • 一個64K的IO會比8個8K的IO速度快,因為前者只請求了一個IO而後者是8個IO。
  • 序列IO會比隨機IO快,因為序列IO相對隨機IO說,即便沒有Cache,序列IO在磁碟處理上也會少些操作。

需要注意,IOPS與IO Response Time有著密切的聯絡。一般情況下,IOPS增加,說明IO請求多了,IO Response Time會相應增加。但是會出現IOPS一直增加,但是IO Response Time變得非常慢,超過20ms甚至幾十ms,這時候的IOPS雖然還在提高,但是意義已經不大,因為整個IO系統的服務時間已經不可取。

Throughput

為吞吐量。這個指標衡量標識了最大的資料傳輸量。如上說明,這個值在順序訪問或者大資料量訪問的情況下會比較重要。尤其在大資料量寫的時候。

吞吐量不像IOPS影響因素很多,吞吐量一般受限於一些比較固定的因素,如:網路頻寬、IO傳輸介面的頻寬、硬碟介面頻寬等。一般他的值就等於上面幾個地方中某一個的瓶頸。

一些概念

 IO Chunk Size

即單個IO操作請求資料的大小。一次IO操作是指從發出IO請求到返回資料的過程。IO Chunk Size與應用或業務邏輯有著很密切的關係。比如像Oracle一類資料庫,由於其block size一般為8K,讀取、寫入時都此為單位,因此,8K為這個系統主要的IO Chunk Size。IO Chunk Size

小,考驗的是IO系統的IOPS能力;IO Chunk Size大,考驗的時候IO系統的IO吞吐量。

Queue Deep

熟悉資料庫的人都知道,SQL是可以批量提交的,這樣可以大大提高操作效率。IO請求也是一樣,IO請求可以積累一定資料,然後一次提交到儲存系統,這樣一些相鄰的資料塊操作可以進行合併,減少物理IO數。而且Queue Deep如其名,就是設定一起提交的IO請求數量的。一般Queue Deep在IO驅動層面上進行配置。

Queue Deep與IOPS有著密切關係。Queue Deep主要考慮批量提交IO請求,自然只有IOPS是瓶頸的時候才會有意義,如果IO都是大IO,磁碟已經成瓶頸,Queue Deep意義也就不大了。一般來說,IOPS的峰值會隨著Queue Deep的增加而增加(不會非常顯著),Queue Deep一般小於256。

隨機訪問(隨機IO)、順序訪問(順序IO

隨機訪問的特點是每次IO請求的資料在磁碟上的位置跨度很大(如:分佈在不同的扇區),因此N個非常小的IO請求(如:1K),必須以N次IO請求才能獲取到相應的資料。

順序訪問的特點跟隨機訪問相反,它請求的資料在磁碟的位置是連續的。當系統發起N個非常小的IO請求(如:1K)時,因為一次IO是有代價的,系統會取完整的一塊資料(如4K、8K),所以當第一次IO完成時,後續IO請求的資料可能已經有了。這樣可以減少IO請求的次數。這也就是所謂的預取。

隨機訪問和順序訪問同樣是有應用決定的。如資料庫、小檔案的儲存的業務,大多是隨機IO。而視訊類業務、大檔案存取,則大多為順序IO。

選取合理的觀察指標:

以上各指標中,不用的應用場景需要觀察不同的指標,因為應用場景不同,有些指標甚至是沒有意義的。

隨機訪問和IOPS: 在隨機訪問場景下,IOPS往往會到達瓶頸,而這個時候去觀察Throughput,則往往遠低於理論值。

順序訪問和Throughput:在順序訪問的場景下,Throughput往往會達到瓶頸(磁碟限制或者頻寬),而這時候去觀察IOPS,往往很小。

檔案系統各有不同,其最主要的目標就是解決磁碟空間的管理問題,同時提供高效性、安全性。如果在分散式環境下,則有相應的分散式檔案系統。Linux上有ext系列,Windows上有Fat和NTFS。如圖為一個linux下檔案系統的結構。

其中VFS(Virtual File System)是Linux Kernel檔案系統的一個模組,簡單看就是一個Adapter,對下遮蔽了下層不同檔案系統之間的差異,對上為作業系統提供了統一的介面.

中間部分為各個不同檔案系統的實現。

再往下是Buffer Cache和Driver。

檔案系統的結構

各種檔案系統實現方式不同,因此效能、管理性、可靠性等也有所不同。下面為Linux Ext2(Ext3)的一個大致檔案系統的結構。

Boot Block存放了載入程式。

Super Block存放了整個檔案系統的一些全域性引數,如:卷名、狀態、塊大小、塊總數。他在檔案系統被mount時讀入記憶體,在umount時被釋放。

上圖描述了Ext2檔案系統中很重要的三個資料結構和他們之間的關係。

Inode:Inode是檔案系統中最重要的一個結構。如圖,他裡面記錄了檔案相關的所有資訊,也就是我們常說的meta資訊。包括:檔案型別、許可權、所有者、大小、atime等。Inode裡面也儲存了指向實際檔案內容資訊的索引。其中這種索引分幾類:

  • 直接索引:直接指向實際內容資訊,公有12個。因此如果,一個檔案系統block size為1k,那麼直接索引到的內容最大為12k
  • 間接索引
  • 兩級間接索引
  • 三級間接索引

如圖:

Directory代表了檔案系統中的目錄,包括了當前目錄中的所有Inode資訊。其中每行只有兩個資訊,一個是檔名,一個是其對應的Inode。需要注意,Directory不是檔案系統中的一個特殊結構,他實際上也是一個檔案,有自己的Inode,而它的檔案內容資訊裡面,包括了上面看到的那些檔名和Inode的對應關係。如下圖:

Data Block即存放檔案的時間內容塊。Data Block大小必須為磁碟的資料塊大小的整數倍,磁碟一般為512位元組,因此Data Block一般為1K、2K、4K。

Buffer Cache

Buffer & Cache

雖然Buffer和Cache放在一起了,但是在實際過程中Buffer和Cache是完全不同了。Buffer一般對於寫而言,也叫“緩衝區”,緩衝使得多個小的資料塊能夠合併成一個大資料塊,一次性寫入;Cache一般對於讀而且,也叫“快取”,避免頻繁的磁碟讀取。如圖為Linux的free命令,其中也是把Buffer和Cache進行區分,這兩部分都算在了free的記憶體。

Buffer Cache

Buffer Cache中的快取,本質與所有的快取都是一樣,資料結構也是類似,下圖為VxSF的一個Buffer Cache結構。

這個資料結構與memcached和Oracle SGA的buffer何等相似。左側的hash chain完成資料塊的定址,上方的的連結串列記錄了資料塊的狀態。

Buffer vs Direct I/O

檔案系統的Buffer和Cache在某些情況下確實提高了速度,但是反之也會帶來一些負面影響。一方面檔案系統增加了一箇中間層,另外一方面,當Cache使用不當、配置不好或者有些業務無法獲取cache帶來的好處時,cache則成為了一種負擔。

       適合Cache的業務:序列的大資料量業務,如:NFS、FTP。

       不適合Cache的業務:隨機IO的業務。如:Oracle,小檔案讀取。

塊裝置、字元裝置、裸裝置

這幾個東西看得很暈,找了一些資料也沒有找到很準確的說明。

從硬體裝置的角度來看,

  • 塊裝置就是以塊(比如磁碟扇區)為單位收發資料的裝置,它們支援緩衝和隨機訪問(不必順序讀取塊,而是可以在任何時候訪問任何塊)等特性。塊裝置包括硬碟、CD-ROM 和 RAM 盤。
  • 字元裝置則沒有可以進行物理定址的媒體。字元裝置包括串列埠和磁帶裝置,只能逐字元地讀取這些裝置中的資料。

從作業系統的角度看(對應作業系統的裝置檔案型別的b和c),

# ls -l /dev/*lv

brw-------   1 root     system       22,  2 May 15 2007  lv

crw-------   2 root     system       22,  2 May 15 2007  rlv

  •  塊裝置能支援緩衝和隨機讀寫。即讀取和寫入時,可以是任意長度的資料。最小為1byte。對塊裝置,你可以成功執行下列命令:dd if=/dev/zero of=/dev/vg01/lv bs=1 count=1。即:在裝置中寫入一個位元組。硬體裝置是不支援這樣的操作的(最小是512),這個時候,作業系統首先完成一個讀取(如1K,作業系統最小的讀寫單位,為硬體裝置支援的資料塊的整數倍),再更改這1k上的資料,然後寫入裝置。
  • 字元裝置只能支援固定長度資料的讀取和寫入,這裡的長度就是作業系統能支援的最小讀寫單位,如1K,所以塊裝置的緩衝功能,這裡就沒有了,需要使用者自己來完成。由於讀寫時不經過任何緩衝區,此時執行dd if=/dev/zero of=/dev/vg01/lv bs=1 count=1,這個命令將會出錯,因為這裡的bs(block size)太小,系統無法支援。如果執行dd if=/dev/zero of=/dev/vg01/lv bs=1024 count=1,則可以成功。這裡的block size有OS核心引數決定。

如上,相比之下,字元裝置在使用更為直接,而塊裝置更為靈活。檔案系統一般建立在塊裝置上,而為了追求高效能,使用字元裝置則是更好的選擇,如Oracle的裸裝置使用。

裸裝置

裸裝置也叫裸分割槽,就是沒有經過格式化、沒有檔案系統的一塊儲存空間。可以寫入二進位制內容,但是內容的格式、其中資訊的組織等問題,需要使用它的人來完成。檔案系統就是建立在裸裝置之上,並完成裸裝置空間的管理。

CIO

CIO即並行IO(Concurrent IO)。在檔案系統中,當某個檔案被多個程序同時訪問時,就出現了Inode競爭的問題。一般地,讀操作使用的共享鎖,即:多個讀操作可以併發進行,而寫操作使用排他鎖。當鎖被寫程序佔用時,其他所有操作均阻塞。因此,當這樣的情況出現時,整個應用的效能將會大大降低。如圖:

CIO就是為了解決這個問題。而且CIO帶來的效能提高直逼裸裝置。當檔案系統支援CIO並開啟CIO時,CIO預設會開啟檔案系統的Direct IO,即:讓IO操作不經過Buffer直接進行底層資料操作。由於不經過資料Buffer,在檔案系統層面就無需考慮資料一致性的問題,因此,讀寫操作可以並行執行。

在最終進行資料儲存的時候,所有操作都會序列執行,CIO把這個事情交個了底層的driver。


LVM(邏輯卷管理),位於作業系統和硬碟之間,LVM遮蔽了底層硬碟帶來的複雜性。最簡單的,LVM使得N塊硬碟在OS看來成為一塊硬碟,大大提高了系統可用性。

LVM的引入,使得檔案系統和底層磁碟之間的關係變得更為靈活,而且更方便關係。LVM有以下特點:

  • 統一進行磁碟管理。按需分配空間,提供動態擴充套件。
  • 條帶化(Striped)
  • 映象(mirrored)
  • 快照(snapshot)

LVM可以做動態磁碟擴充套件,想想看,當系統管理員發現應用空間不足時,敲兩個命令就完成空間擴充套件,估計做夢都要笑醒:)

LVM的磁碟管理方式

LVM中有幾個很重要的概念:

  • PV(physical volume):物理卷。在LVM中,一個PV對應就是作業系統能看見的一塊物理磁碟,或者由儲存裝置分配作業系統的lun。一塊磁碟唯一對應一個PV,PV建立以後,說明這塊空間可以納入到LVM的管理。建立PV時,可以指定PV大小,即可以把整個磁碟的部分納入PV,而不是全部磁碟。這點在表面上看沒有什麼意義,但是如果主機後面接的是儲存裝置的話就很有意義了,因為儲存裝置分配的lun是可以動態擴充套件的,只有當PV可以動態擴充套件,這種擴充套件性才能向上延伸。
  • VG(volume group):卷組。一個VG是多個PV的集合,簡單說就是一個VG就是一個磁碟資源池。VG對上遮蔽了多個物理磁碟,上層是使用時只需考慮空間大小的問題,而VG解決的空間的如何在多個PV上連續的問題。
  • LV(logical volume):邏輯卷。LV是最終可供使用卷,LV在VG中建立,有了VG,LV建立是隻需考慮空間大小等問題,對LV而言,他看到的是一直聯絡的地址空間,不用考慮多塊硬碟的問題。

有了上面三個,LVM把單個的磁碟抽象成了一組連續的、可隨意分配的地址空間。除上面三個概念外,還有一些其他概念:

  • PE(physical extend): 物理擴充套件塊。LVM在建立PV,不會按位元組方式去進行空間管理。而是按PE為單位。PE為空間管理的最小單位。即:如果一個1024M的物理盤,LVM的PE為4M,那麼LVM管理空間時,會按照256個PE去管理。分配時,也是按照分配了多少PE、剩餘多少PE考慮。
  • LE(logical extend):邏輯擴充套件塊。類似PV,LE是建立LV考慮,當LV需要動態擴充套件時,每次最小的擴充套件單位。

對於上面幾個概念,無需刻意去記住,當你需要做這麼一個東西時,這些概念是自然而然的。PV把物理硬碟轉換成LVM中對於的邏輯(解決如何管理物理硬碟的問題),VG是PV的集合(解決如何組合PV的問題),LV是VG上空間的再劃分(解決如何給OS使用空間的問題);而PE、LE則是空間分配時的單位。

如圖,為兩塊18G的磁碟組成了一個36G的VG。此VG上劃分了3個LV。其PE和LE都為4M。其中LV1只用到了sda的空間,而LV2和LV3使用到了兩塊磁碟。

串聯、條帶化、映象

串聯(Concatenation): 按順序使用磁碟,一個磁碟使用完以後使用後續的磁碟。

條帶化(Striping): 交替使用不同磁碟的空間。條帶化使得IO操作可以並行,因此是提高IO效能的關鍵。另外,Striping也是RAID的基礎。如:VG有2個PV,LV做了條帶數量為2的條帶化,條帶大小為8K,那麼當OS發起一個16K的寫操作時,那麼剛好這2個PV對應的磁碟可以對整個寫入操作進行並行寫入。

Striping帶來好處有:
  • 併發進行資料處理。讀寫操作可以同時傳送在多個磁碟上,大大提高了效能。

Striping帶來的問題:

  • 資料完整性的風險。Striping導致一份完整的資料被分佈到多個磁碟上,任何一個磁碟上的資料都是不完整,也無法進行還原。一個條帶的損壞會導致所有資料的失效。因此這個問題只能通過儲存裝置來彌補。
  • 條帶大小的設定很大程度決定了Striping帶來的好處。如果條帶設定過大,一個IO操作最終還是發生在一個磁碟上,無法帶來並行的好處;當條帶設定國小,本來一次並行IO可以完成的事情會最終導致了多次並行IO。

映象(mirror)

如同名字。LVM提供LV映象的功能。即當一個LV進行IO操作時,相同的操作發生在另外一個LV上。這樣的功能為資料的安全性提供了支援。如圖,一份資料被同時寫入兩個不同的PV。

使用mirror時,可以獲得一些好處:

  • 讀取操作可以從兩個磁碟上獲取,因此讀效率會更好些。
  • 資料完整複雜了一份,安全性更高。
但是,伴隨也存在一些問題:
  • 所有的寫操作都會同時傳送在兩個磁碟上,因此實際傳送的IO是請求IO的2倍
  • 由於寫操作在兩個磁碟上發生,因此一些完整的寫操作需要兩邊都完成了才算完成,帶來了額外負擔。
  • 在處理序列IO時,有些IO走一個磁碟,另外一些IO走另外的磁碟,一個完整的IO請求會被打亂,LVM需要進行IO資料的合併,才能提供給上層。像一些如預讀的功能,由於有了多個數據獲取同道,也會存在額外的負擔。

快照(Snapshot)

快照如其名,他儲存了某一時間點磁碟的狀態,而後續資料的變化不會影響快照,因此,快照是一種備份很好手段。

但是快照由於儲存了某一時間點資料的狀態,因此在資料變化時,這部分資料需要寫到其他地方,隨著而來回帶來一些問題。關於這塊,後續儲存也涉及到類似的問題,後面再說。

這部分值得一說的是多路徑問題。IO部分的高可用性在整個應用系統中可以說是最關鍵的,應用層可以壞掉一兩臺機器沒有問題,但是如果IO不通了,整個系統都沒法使用。如圖為一個典型的SAN網路,從主機到磁碟,所有路徑上都提供了冗餘,以備發生通路中斷的情況。

  • OS配置了2塊光纖卡,分別連不同交換機
  • SAN網路配置了2個交換機
  • 儲存配置了2個Controller,分別連不同交換機

如上圖結構,由於存在兩條路徑,對於儲存劃分的一個空間,在OS端會看到兩個(兩塊磁碟或者兩個lun)。可怕的是,OS並不知道這兩個東西對應的其實是一塊空間,如果路徑再多,則OS會看到更多。還是那句經典的話,“計算機中碰到的問題,往往可以通過增加的一箇中間層來解決”,於是有了多路徑軟體。他提供了以下特性:

  • 把多個對映到同一塊空間的路徑合併為一個提供給主機
  • 提供fail over的支援。當一條通路出現問題時,及時切換到其他通路
  • 提供load balance的支援。即同時使用多條路徑進行資料傳送,發揮多路徑的資源優勢,提高系統整體頻寬。

Fail over的能力一般OS也可能支援,而load balance則需要與儲存配合,所以需要根據儲存不同配置安裝不同的多通路軟體。

多路徑除了解決了高可用性,同時,多條路徑也可以同時工作,提高系統性能。

Raid很基礎,但是在儲存系統中佔據非常重要的地位,所有涉及儲存的書籍都會提到RAID。RAID通過磁碟冗餘的方式提高了可用性和可高性,一方面增加了資料讀寫速度,另一方面增加了資料的安全性。

RAID 0

對資料進行條帶化。使用兩個磁碟交替存放連續資料。因此可以實現併發讀寫,但帶來的問題是如果一個磁碟損壞,另外一個磁碟的資料將失去意義。RAID 0最少需要2塊盤。

RAID 1

對資料進行映象。資料寫入時,相同的資料同時寫入兩塊盤。因此兩個盤的資料完全一致,如果一塊盤損壞,另外一塊盤可以頂替使用,RAID 1帶來了很好的可靠性。同時讀的時候,資料可以從兩個盤上進行讀取。但是RAID 1帶來的問題就是空間的浪費。兩塊盤只提供了一塊盤的空間。RAID 1最少需要2塊盤。

RAID 5 和 RAID 4

使用多餘的一塊校驗盤。資料寫入時,RAID 5需要對資料進行計算,以便得出校驗位。因此,在寫效能上RAID 5會有損失。但是RAID 5兼顧了效能和安全性。當有一塊磁碟損壞時,RAID 5可以通過其他盤上的資料對其進行恢復。

如圖可以看出,右下角為p的就是校驗資料。可以看到RAID 5的校驗資料依次分佈在不同的盤上,這樣可以避免出現熱點盤(因為所有寫操作和更新操作都需要修改校驗資訊,如果校驗都在一個盤做,會導致這個盤成為寫瓶頸,從而拖累整體效能,RAID 4的問題)。RAID 5最少需要3塊盤。

RAID 6

RAID 6與RAID 5類似。但是提供了兩塊校驗盤(下圖右下角為p和q的)。安全性更高,寫效能更差了。RAID 0最少需要4塊盤。

RAID 10(Striped mirror)

RAID 10是RAID 0 和RAID 1的結合,同時兼顧了二者的特點,提供了高效能,但是同時空間使用也是最大。RAID 10最少需要4塊盤。

需要注意,使用RAID 10來稱呼其實很容易產生混淆,因為RAID 0+1和RAID 10基本上只是兩個數字交換了一下位置,但是對RAID來說就是兩個不同的組成。因此,更容易理解的方式是“Striped mirrors”,即:條帶化後的映象——RAID 10;或者“mirrored stripes”,即:映象後的條帶化。比較RAID 10和RAID 0+1,雖然最終都是用到了4塊盤,但是在資料組織上有所不同,從而帶來問題。RAID 10在可用性上是要高於RAID 0+1的:

  • RAID 0+1 任何一塊盤損壞,將失去冗餘。如圖4塊盤中,右側一組損壞一塊盤,左側一組損壞一塊盤,整個盤陣將無法使用。而RAID 10左右各損壞一塊盤,盤陣仍然可以工作。
  • RAID 0+1 損壞後的恢復過程會更慢。因為先經過的mirror,所以左右兩組中儲存的都是完整的資料,資料恢復時,需要完整恢復所以資料。而RAID 10因為先條帶化,因此損壞資料以後,恢復的只是本條帶的資料。如圖4塊盤,資料少了一半。
RAID 50 RAID 50 同RAID 10,先做條帶化以後,在做RAID 5。兼顧效能,同時又保證空間的利用率。RAID 50最少需要6塊盤。 總結:
  • RAID與LVM中的條帶化原理上類似,只是實現層面不同。在儲存上實現的RAID一般有專門的晶片來完成,因此速度上遠比LVM塊。也稱硬RAID。
  • 如上介紹,RAID的使用是有風險的,如RAID 0,一塊盤損壞會導致所有資料丟失。因此,在實際使用中,高效能環境會使用RAID 10,兼顧效能和安全;一般情況下使用RAID 5(RAID 50),兼顧空間利用率和效能;

DAS、SAN和NAS

為了滿足人們不斷擴大的需求,儲存方案也是在發展的。而DAS、SAN、NAS直接反映這種反映了這種趨勢。

  • 單臺主機。在這種情況下,儲存作為主機的一個或多個磁碟存在,這樣侷限性也是很明顯的。由於受限於主機空間,一個主機只能裝一塊到幾塊硬碟,而硬碟空間時受限的,當磁碟滿了以後,你不得不為主機更換更大空間的硬碟。
  • 獨立儲存空間。為了解決空間的問題,於是考慮把磁碟獨立出來,於是有了DAS(Direct Attached Storage),即:直連儲存。DAS就是一組磁碟的集合體,資料讀取和寫入等也都是由主機來控制。但是,隨之而來,DAS又面臨了一個他無法解決的問題——儲存空間的共享。接某個主機的JBOD(Just a Bunch Of Disks,磁碟組),只能這個主機使用,其他主機無法用。因此,如果DAS解決空間了,那麼他無法解決的就是如果讓空間能夠在多個機器共享。因為DAS可以理解為與磁碟互動,DAS處理問題的層面相對更低。使用協議都是跟磁碟互動的協議
  • 獨立的儲存網路。為了解決共享的問題,借鑑乙太網的思想,於是有了SAN(Storage Area Network),即:儲存網路。對於SAN網路,你能看到兩個非常特點,一個就是光纖網路,另一個是光纖交換機。SAN網路由於不會之間跟磁碟互動,他考慮的更多是資料存取的問題,因此使用的協議相對DAS層面更高一些。
    • 光纖網路:對於儲存來說,與乙太網很大的一個不同就是他對頻寬的要求非常高,因此SAN網路下,光纖成為了其連線的基礎。而其上的光纖協議相比乙太網協議而言,也被設計的更為簡潔,效能也更高。
    • 光纖交換機:這個類似乙太網,如果想要做到真正的“網路”,交換機是基礎。
  • 網路檔案系統。儲存空間可以共享,那檔案也是可以共享的。NAS(Network attached storage)相對上面兩個,看待問題的層面更高,NAS是在檔案系統級別看待問題。因此他面的不再是儲存空間,而是單個的檔案。因此,當NAS和SAN、DAS放在一起時,很容易引起混淆。NAS從檔案的層面考慮共享,因此NAS相關協議都是檔案控制協議。
    • NAS解決的是檔案共享的問題;SAN(DAS)解決的是儲存空間的問題。
    • NAS要處理的物件是檔案;SAN(DAS)要處理的是磁碟。
    • 為NAS服務的主機必須是一個完整的主機(有OS、有檔案系統,而儲存則不一定有,因為可以他後面又接了一個SAN網路),他考慮的是如何在各個主機直接高效的共享檔案;為SAN提供服務的是儲存裝置(可以是個完整的主機,也可以是部分),它考慮的是資料怎麼分佈到不同磁碟。
    • NAS使用的協議是控制檔案的(即:對檔案的讀寫等);SAN使用的協議是控制儲存空間的(即:把多長的一串二進位制寫到某個地址)

如圖,對NAS、SAN、DAS的組成協議進行了劃分,從這裡也能很清晰的看出他們之間的差別。

NAS:涉及SMB協議、NFS協議,都是網路檔案系統的協議。

SAN:有FC、iSCSI、AOE,都是網路資料傳輸協議。

DAS:有PATA、SATA、SAS等,主要是磁碟資料傳輸協議。

    從DAS到SAN,在到NAS,在不同層面對儲存方案進行的補充,也可以看到一種從低階到高階的發展趨勢。而現在我們常看到一些分散式檔案系統(如hadoop等)、資料庫的sharding等,從儲存的角度來說,則是在OS層面(應用)對資料進行儲存。從這也能看到一種技術發展的趨勢。

跑在乙太網上的SAN

SAN網路並不是只能使用光纖和光纖協議,當初之所以使用FC,傳輸效率是一個很大的問題,但是乙太網發展到今天被不斷的完善、加強,頻寬的問題也被不斷的解決。因此,乙太網上的SAN或許會成為一個趨勢。

  • FCIP

如圖兩個FC的SAN網路,通過FCIP實現了兩個SAN網路資料在IP網路上的傳輸。這個時候SAN網路還是以FC協議為基礎,還是使用光纖。

  • iFCP

通過iFCP方式,SAN網路由FC的SAN網路演變為IP SAN網路,整個SAN網路都基於了IP方式。但是主機和儲存直接使用的還是FC協議。只是在接入SAN網路的時候通過iFCP進行了轉換

  • iSCSI

iSCSI是比較主流的IP SAN的提供方式,而且其效率也得到了認可。

       對於iSCSI,最重要的一點就是SCSI協議。SCSI(Small Computer Systems Interface)協議是計算機內部的一個通用協議。是一組標準集,它定義了與大量裝置(主要是與儲存相關的裝置)通訊所需的介面和協議。如圖,SCSI為block device drivers之下。

從SCIS的分層來看,共分三層:

高層:提供了與OS各種裝置之間的介面,實現把OS如:Linux的VFS請求轉換為SCSI請求

中間層:實現高層和底層之間的轉換,類似一個協議閘道器。

底層:完成於具體物理裝置之間的互動,實現真正的資料處理。