RAID與其在Linux上的實現


參考資料:

RAID

data striping

spanned volume

從raid0到raid7,raid陣列各級別介紹

本文所使用的圖片來源於互聯網,若有侵權,煩請聯系,謝謝。

簡介

RAID出現的目的是為了數據的冗余,或者性能的提升,或者兩者兼顧。早期想實現這樣的功能,可能需要購買一些基於大型機(mainframe)的設備,但是價格過於昂貴,后來就有些人發明了RAID技術將多塊廉價的磁盤組合在了一起,實現了和大型機設備同等的功能。

RAID,早期的全稱是冗余廉價磁盤陣列(Redundant Array of Inexpensive Disks),主要是相比於以往的昂貴的SLED(Single Large Expensive Disk),后改名為冗余獨立磁盤陣列(Redundant Array of Independent Disks),畢竟現在的RAID控制卡也已經不便宜了。

基於不同級別的冗余和性能要求,RAID有不同的級別(level)。不同的級別也決定了可靠性(reliability)、可用性(availability)、性能(performance)和容量(capacity)的不同。

許多RAID級別采用了一種錯誤保護機制,叫做奇偶校驗(parity)。大部分情況使用的是異或運算(XOR),不過RAID 6則使用了兩種獨立的奇偶校驗方法。

不同的RAID級別,使用不同的數字來表示,例如RAID 0、RAID 1等等。

RAID級別按照種類划分有標准(standard)級別、嵌套/混合(nested/hybrid)級別和非標准(non-standard)級別。RAID級別是由SINA(Storage Networking Industry Association)組織所定義的。

接下來我們就來一一介紹這幾種RAID。

 

標准級別

RAID 0

基於striping方式(data striping是一種切割邏輯上連續數據的技術,例如切割文件,使得連續的片段可以被存儲在不同的物理存儲設備上。)來組織數據,不具備鏡像(mirror,即數據冗余)和校驗的功能。如圖所示。

一個文件會被切割成多個block,假設有8個,有A1~A8表示,那么會依次存入陣列中的每個磁盤當中。

優點:

  1. 讀寫性能提升,理論上有n塊磁盤,就可以帶來n倍的性能提升,因為讀寫是並行的。
  2. 存儲容量提升,陣列總容量為n塊磁盤之和。如果磁盤的容量不是相等的,則總容量為n倍的最小磁盤容量。其他RAID級別遇到磁盤容量不同的時候,也是以最小磁盤容量為准。接下來我們假設所有RAID的磁盤容量都是相同的,一般在生產環境中,陣列中的磁盤的容量、型號等也都會是一模一樣的。

缺點:

  1. 沒有數據冗余能力,1塊硬盤損壞則整個RAID無法使用,數據全部丟失。並且隨着陣列中磁盤數量的增加,發生損壞的概率就越大。
  2. 沒有校驗能力,無法基於校驗碼進行數據恢復。

其他:

  1. 至少需要2塊硬盤。

RAID 1

基於鏡像(mirroring)的方式,當寫入數據的時候,會同時寫入每個磁盤設備。

優點:

  1. 具備數據冗余能力,只要陣列中還有一塊硬盤處於工作狀態,那么整個陣列就依然可用。
  2. 讀性能提升,如果RAID控制器足夠強大,則讀性能可接近於RAID 0,不過實際實現中,應該無法達到。

缺點:

  1. 寫性能下降。由於同一個block的數據需要被寫入陣列中的每一個磁盤中,因此寫性能下降。磁盤數越多,寫性能下降越多。最慢的磁盤會限制整個陣列的寫性能。
  2. 沒有校驗能力,無法基於校驗碼進行數據恢復。

其他:

  1. 存儲容量保持不變。總容量為單塊磁盤容量。
  2. 至少需要2塊磁盤。

RAID 2

數據的組織方式類似RAID 0,通過striping技術以位(bit)為單位將數據切割至多塊磁盤上。使用漢明碼(hamming-code)作為校驗碼,具備數據恢復能力,但是需要多塊磁盤作為校驗盤。所有磁盤的主軸旋轉是同步的。

目前已被棄用!!!

RAID 3

類似RAID 2。區別在於RAID 3是基於字節(byte)級別,使用非漢明碼的校驗碼,所以校驗碼只需存儲在一塊磁盤中。

目前已被棄用!!!

RAID 4

類似於RAID 2和3。區別在於RAID 4是基於塊(block)級別,校驗碼存儲在一塊磁盤上。RAID 4相對於2和3的最大優點在於I/O並行性(parallelism):在2和3中,一次簡單的讀操作會從陣列中的所有磁盤讀取數據,而4則不需要。

由於只有一塊校驗盤,每次寫入數據的時候需要計算校驗碼,隨着磁盤數的增加,校驗盤的性能會成為整個陣列的瓶頸。

目前RAID 4的實現大部分已被私有技術RAID DP所取代,RAID DP使用了兩塊校驗盤。

注意:圖片可能有點錯誤,DISK 2中存儲的應該是BLOCK A3、B3、C3和D3的數據。

優點:

  1. 讀寫性能提升,讀性能理論為n倍的數據盤,寫性能理論小於n倍的數據盤且隨着數據盤的增加,寫性能越來越受制於校驗盤。
  2. 具有數據恢復能力。
  3. 存儲容量提升,為磁盤總容量減去校驗盤容量(n-1)。

缺點:

  1. 無鏡像能力,雖然存在數據恢復能力,但是數據盤損壞后,基於校驗碼恢復數據會有額外的計算開銷。
  2. 校驗盤瓶頸問題。

其他:

  1. 至少需要3塊磁盤。

RAID 5

類似於RAID 4,RAID 5基於塊(block)級別切割數據至多個磁盤,同樣具備校驗碼。但是,最大的區別在於RAID 5的校驗碼不是存放在專門的磁盤上,而是分布式地存儲在陣列中的每個磁盤中,這就解決了RAID 4的寫性能受制於校驗盤的問題了。截止目前,涉及校驗的RAID,它們的校驗碼都是只計算一次並保留一份,這也叫做“單校驗概念”(single-parity concept)。像這類單校驗的設計,當陣列越來越龐大的時候,容易受到系統故障的影響,這里的系統故障指的是磁盤損壞陣列重建(rebuild)時間以及重建期二次磁盤損壞幾率。詳見:Increasing rebuild time and failure probability

優點:

  1. 讀寫性能提升,理論為n倍的磁盤,解決了RAID 4中的校驗盤瓶頸問題。
  2. 具有數據恢復能力。
  3. 存儲容量提升,為磁盤總容量減去校驗碼占用容量(n-1),校驗碼占用的容量約為一個磁盤容量。

缺點:

  1. 無鏡像能力,雖然存在數據恢復能力,但是數據盤損壞后,基於校驗碼恢復數據會有額外的計算開銷。
  2. 單校驗問題,此前的所有具備校驗能力的RAID亦均有此問題。

其他:

  1. 至少需要3塊磁盤。

RAID 6

類似於RAID 5,RAID 6基於塊(block)級別切割數據至多個磁盤,具備分布式校驗碼。只不過是使用了雙校驗碼(double-parity)機制。雙校驗支持損壞至多2塊磁盤。這使得更大的RAID陣列更加實用,尤其對於高可用系統,因為大容量的陣列需要更長的時間重建。至少需要4塊磁盤。和RAID 5一樣,單塊磁盤故障會降低整體陣列性能,直到故障盤被替換。如果磁盤的容量和陣列的容量越大的話,那么越應該考慮使用RAID 6來替代RAID 5。RAID 10同樣也最小化了這些問題。

優點:

  1. 讀寫性能提升,寫性能可能稍微遜色於RAID 5,因為要計算2種校驗碼。
  2. 具備數據恢復能力,允許損壞至多2塊磁盤。
  3. 存儲容量提升,n-1。
  4. 新增雙校驗機制,解決單校驗的問題,此類設計更適合支持大容量陣列並提高其可用性。

缺點:

  1. 必須犧牲2塊磁盤的容量存放校驗碼。
  2. 無鏡像能力,雖然存在數據恢復能力,但是數據盤損壞后,基於校驗碼恢復數據會有額外的計算開銷。不過雙校驗應該可以加快數據恢復的時間。

其他:

  1. 至少需要4塊磁盤。

 

嵌套級別

RAID中的每個元素(組成成分),可以是獨立磁盤,也可以是一個RAID陣列。對於后者,我們稱之為RAID嵌套。

RAID 01

也叫作RAID 0+1或者RAID 0&1,先將磁盤制作成RAID 0,再將每個RAID 0組合成RAID 1。如圖所示。

任何一塊磁盤損壞都會導致其中一個stripe(基於striping技術的RAID 0,也可叫stripe)不可用,此時整個RAID 01陣列實際上就降級為RAID 0陣列了。該陣列相比RAID 10在重建期會遭遇更高的風險,因為它需要讀取剩下的stripe中的所有磁盤的所有數據而不是其中一塊盤上的所有數據,增加了URE(Unrecoverable Rear Error)的概率並且明顯擴大了重建窗口。

至少需要4塊磁盤。可以采用更多的磁盤,但是這意味着磁盤故障率也會隨之增加,如果陣列只有2個stripe,並且剛好每個stripe各損壞1塊磁盤,那么整個陣列就完了。

按照此圖示的存儲容量為n/2。

因此,RAID 01是不好的,不建議使用。建議使用RAID 10來替代它!!!

RAID 10

也叫作RAID 1+0或者RAID 1&0,先將磁盤制作成RAID 1,再將每個RAID 1組合成RAID 0。如圖所示。

這種陣列相對RAID 01可以承受更多的設備損壞,特別是在單個鏡像卷中的磁盤數量較多的情況下。

按照此圖示的存儲容量為n/2。

 

非RAID架構

關於RAID的常用級別基本已經說明完畢,除了以上幾個RAID級別,還有一些並不是基於RAID技術但是也可以將磁盤數據集合起來的技術,這些技術通常只是簡單地將磁盤堆疊起來使用而已,並不一定具備像RAID一樣的數據冗余和性能提升的功能。

  • JBOD:Just a Bunch Of Disks。
  • SPAN or BIG:字面意義,非縮略詞。
  • MAID:Massive Array of Idle Drives。

詳見:Non-RAID drive architectures

 

實現

RAID的實現主要有兩種,一種是基於硬件俗稱硬RAID,另一種是基於軟件俗稱軟RAID。

硬RAID需要硬件(RAID卡,即RAID控制器)支持,一般是在OS啟動之前,在BIOS中進行RAID的相關配置,並且在OS啟動之后,會有對應RAID卡廠商的私有軟件工具可以進行配置。因為本人沒有相關硬RAID配置經驗以及這只是實驗環境,因此沒有硬RAID相關實現的介紹。

軟RAID的實現方式也有很多種,一般是基於操作系統的某些特性,例如基於Linux內核的md(Multiple Device)或者OpenBSD的softraid。

本文主要闡述如何基於Linux操作系統實現軟RAID。

mdadm

基於Linux的md實現的命令是mdadm,它所支持的RAID級別:LINEAR(類似JBOD)、RAID 0、RAID 1、RAID 4、RAID 5、RAID 6和RAID 10。

OS:CentOS 7.5

mdadm:v4.0

我們的目標是,使用4塊1GB的磁盤,創建RAID 5陣列,其中3塊作為有效(active)盤,1塊作為備用(spare)盤。

創建4塊磁盤,分區,文件系統類型為Linux的RAID(ID:fd)。

[root@C7 ~]# fdisk -l | grep -i "raid"
/dev/sdb1            2048     2097151     1047552   fd  Linux raid autodetect
/dev/sdc1            2048     2097151     1047552   fd  Linux raid autodetect
/dev/sde1            2048     2097151     1047552   fd  Linux raid autodetect
/dev/sdd1            2048     2097151     1047552   fd  Linux raid autodetect

查看內核識別到的分區信息,確保我們剛才所創建的四個磁盤的分區已經被內核識別。

[root@C7 ~]# cat /proc/partitions 
major minor  #blocks  name

   8        0   20971520 sda
   8        1    1048576 sda1
   8        2   19921920 sda2
   8       16    1048576 sdb
   8       17    1047552 sdb1
   8       32    1048576 sdc
   8       33    1047552 sdc1
  11        0    4365312 sr0
   8       64    1048576 sde
   8       65    1047552 sde1
   8       48    1048576 sdd
   8       49    1047552 sdd1
 253        0   17821696 dm-0
 253        1    2097152 dm-1

如果未識別到,則使用partprobe告知內核。警告信息可以忽略。

[root@C7 ~]# partprobe 
Warning: Unable to open /dev/sr0 read-write (Read-only file system).  /dev/sr0 has been opened read-only.

創建磁盤陣列。

[root@C7 ~]# mdadm -C /dev/md0 -l 5 -n 3 -x 1 /dev/sd{b,c,d,e}1
mdadm: Defaulting to version 1.2 metadata
mdadm: array /dev/md0 started.

查看陣列狀態信息

方法一

[root@C7 ~]# cat /proc/mdstat 
Personalities : [raid6] [raid5] [raid4] 
md0 : active raid5 sdd1[4] sde1[3](S) sdc1[1] sdb1[0]
      2091008 blocks super 1.2 level 5, 512k chunk, algorithm 2 [3/3] [UUU]

陣列創建的過程需要時間,例如寫入RAID元數據之類的,想動態查看的話,可以通過watch命令

[root@C7 ~]# watch -n 1 cat /proc/mdstat

方法二

[root@C7 ~]# mdadm -D /dev/md0
/dev/md0:
           Version : 1.2
     Creation Time : Wed Apr  3 14:15:55 2019
        Raid Level : raid5    # RAID級別
        Array Size : 2091008 (2042.00 MiB 2141.19 MB)    # 4塊磁盤,各1GB,1塊備用盤,還有1塊盤的容量為校驗碼,因此陣列可用容量為2GB。
     Used Dev Size : 1045504 (1021.00 MiB 1070.60 MB)
      Raid Devices : 3
     Total Devices : 4
       Persistence : Superblock is persistent

       Update Time : Wed Apr  3 14:16:00 2019
             State : clean    # 陣列的狀態,clean表示干凈狀態,即陣列處於健康工作狀態
    Active Devices : 3
   Working Devices : 4
    Failed Devices : 0
     Spare Devices : 1

            Layout : left-symmetric
        Chunk Size : 512K

Consistency Policy : resync

              Name : C7:0  (local to host C7)
              UUID : ebf794e8:8f01958a:f004744b:7be7a8cf    # 系統重啟后,陣列的設備名稱可能不再是/dev/md0,因此可使用UUID來代替設備名稱寫入/etc/fstab。
            Events : 18

    Number   Major   Minor   RaidDevice State
       0       8       17        0      active sync   /dev/sdb1
       1       8       33        1      active sync   /dev/sdc1
       4       8       49        2      active sync   /dev/sdd1

       3       8       65        -      spare   /dev/sde1

格式化RAID設備並掛載使用

[root@C7 ~]# mkfs -t xfs /dev/md0
meta-data=/dev/md0               isize=512    agcount=8, agsize=65408 blks
         =                       sectsz=512   attr=2, projid32bit=1
         =                       crc=1        finobt=0, sparse=0
data     =                       bsize=4096   blocks=522752, imaxpct=25
         =                       sunit=128    swidth=256 blks
naming   =version 2              bsize=4096   ascii-ci=0 ftype=1
log      =internal log           bsize=4096   blocks=2560, version=2
         =                       sectsz=512   sunit=8 blks, lazy-count=1
realtime =none                   extsz=4096   blocks=0, rtextents=0
[root@C7 ~]# mkdir /raid_data
[root@C7 ~]# mount /dev/md0 /raid_data

創建一個測試的文本文件,輸入一些信息。在下文標記陣列中磁盤為faulty狀態時,我們可以通過測試此文件是否內容可讀取來判斷RAID是否可用。

[root@C7 ~]# cat /raid_data/raid.txt
this is a test file for RAID 5 !!!

手動標記陣列中的一塊有效磁盤為faulty狀態,並觀察備用盤是否自動頂替。

[root@C7 ~]# mdadm /dev/md0 -f /dev/sdd1
mdadm: set /dev/sdd1 faulty in /dev/md0

再次查看狀態會發現一些變化。

[root@C7 ~]# mdadm -D /dev/md0
/dev/md0:
           Version : 1.2
     Creation Time : Wed Apr  3 14:15:55 2019
        Raid Level : raid5
        Array Size : 2091008 (2042.00 MiB 2141.19 MB)
     Used Dev Size : 1045504 (1021.00 MiB 1070.60 MB)
      Raid Devices : 3
     Total Devices : 4
       Persistence : Superblock is persistent

       Update Time : Wed Apr  3 14:45:28 2019
             State : clean, degraded, recovering    # 由於磁盤損壞了1塊,且存在備用盤。備用盤自動頂替,陣列進入重建期,在重建完成前,陣列處於降級模式工作。重建完畢后,狀態又會變回clean了。
    Active Devices : 2
   Working Devices : 3
    Failed Devices : 1
     Spare Devices : 1

            Layout : left-symmetric
        Chunk Size : 512K

Consistency Policy : resync

    Rebuild Status : 65% complete    # 數據重建進度。

              Name : C7:0  (local to host C7)
              UUID : ebf794e8:8f01958a:f004744b:7be7a8cf
            Events : 30

    Number   Major   Minor   RaidDevice State
       0       8       17        0      active sync   /dev/sdb1
       1       8       33        1      active sync   /dev/sdc1
       3       8       65        2      spare rebuilding   /dev/sde1

       4       8       49        -      faulty   /dev/sdd1

待陣列重建完畢,再標記一塊磁盤為faulty狀態。

[root@C7 ~]# mdadm /dev/md0 -f /dev/sdc1
mdadm: set /dev/sdc1 faulty in /dev/md0

此時我們的陣列,就只能工作於降級模式而無法恢復clean了。

[root@C7 ~]# mdadm -D /dev/md0
/dev/md0:
           Version : 1.2
     Creation Time : Wed Apr  3 14:15:55 2019
        Raid Level : raid5
        Array Size : 2091008 (2042.00 MiB 2141.19 MB)
     Used Dev Size : 1045504 (1021.00 MiB 1070.60 MB)
      Raid Devices : 3
     Total Devices : 4
       Persistence : Superblock is persistent

       Update Time : Wed Apr  3 14:47:55 2019
             State : clean, degraded 
    Active Devices : 2
   Working Devices : 2
    Failed Devices : 2
     Spare Devices : 0

            Layout : left-symmetric
        Chunk Size : 512K

Consistency Policy : resync

              Name : C7:0  (local to host C7)
              UUID : ebf794e8:8f01958a:f004744b:7be7a8cf
            Events : 45

    Number   Major   Minor   RaidDevice State
       0       8       17        0      active sync   /dev/sdb1
       -       0        0        1      removed
       3       8       65        2      active sync   /dev/sde1

       1       8       33        -      faulty   /dev/sdc1
       4       8       49        -      faulty   /dev/sdd1

無論陣列處於重建期或者降級模式,測試文件都是可讀的。

如果該陣列不使用了,那么我們應該先卸載陣列,再關閉它。

[root@C7 ~]# umount /dev/md0
[root@C7 ~]# mdadm -S /dev/md0
mdadm: stopped /dev/md0
[root@C7 ~]# mdadm -D /dev/md0
mdadm: cannot open /dev/md0: No such file or directory

關閉后,陣列設備文件消失。

 

總結

  1. 實際生產環境中,數據的完整性和性能是重要的,因此不應該使用軟RAID,而應該采用硬RAID。
  2. 不同的RAID卡廠商的配置方式不同,萬變不離其宗,了解RAID原理各級別特性比RAID實現更重要。
  3. 本文關於Linux上的軟RAID實現只是簡單闡述,切勿直接拿來在生產環境使用。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM