Raid——軟件磁盤陣列
1. 軟件磁盤陣列(Software RAID)
Q:
什么是RAID?
RAID機制的功能是什么?
有哪些等級?
什么是硬件、軟件磁盤陣列?
Linux支持什么樣的軟件磁盤陣列?
1.1 什么是RAID
磁盤陣列全名是[ Redundant Arrays of Inexpensive Disks, RAID],英翻的意思是:容錯式廉價磁盤陣列。RAID可以透過一個技術(軟件或硬件),將多個較小的磁盤整合成為一個較大的磁盤裝置;而這個較大的磁盤功能不止是存儲,他還具有數據保護的功能。整個RAID由於選擇的等級(level)不同,而使得整合后的磁盤具有不同的功能,基本常見的level有以下幾種:
-
RAID-0(等量模式,stripe):效能最佳
這種模式如果使用相同型號與容量的磁盤來組成時,效果較佳。這種模式的RAID會將磁盤先切出等量的區塊(名為chumk,一般可設定4K~1M之間),然后當一個文件要寫入RAID時,該文件會依據chunk的大小切割好,之后再依序放到各個磁盤里面去。由於每個磁盤會交錯的存放數據,因此當數據要寫入RAID時,數據會被等量的放置在各個磁盤上面。舉例來說,有兩個磁盤組成RAID-0,當有100MB的數據要寫入時,每個磁盤會被分配到50MB的儲存量。RAID-0的示意圖如下:
上圖的意思是,在組成RAID-0時,每個磁盤(Disk A 與 Disk B)都會先被區隔成為小區塊(chunk).
當有數據要寫入RAID時,資料會先被切割成符合小區塊的大小,然后再依序一個一個的放置到不同的磁盤去。由於數據已經先被切割並且依次放置到不同的磁盤上面,因此每個磁盤所復制的數據量都降低了,這種情況來看,越多磁盤組成的RAID-0效能會越好,因為每顆負責的資料量都降低了,資料可以分散讓多顆磁盤來儲存,效能會更好,磁盤的總容量也會變大,每個磁盤的容量加起來是RAID-0的總容量。
缺點:使用RAID-0,要自行負擔數據毀壞的風險,文件是被切割成為適合每顆磁盤分區區塊的大小,再依序放置到各個磁盤中,如果某一個磁盤損壞了,文件數據就少了一部分,這個文件就損毀了。由於每個文件都是這樣存放的,因此RAID-0 只要有任何一顆磁盤損壞,在RAID上面的所有數據都會遺失而無法讀取。
另外,如果使用不同容量的磁盤來組成 RAID-0 時,由於數據是一直等量的依序放置到不同磁盤中,當小容量磁盤的區塊被用完了,那么所有的數據都將被寫入到最大的那顆磁盤去。舉例說明:使用200G與500G組成 RAID-0 ,那么最初的400GB數據可同時寫入兩顆磁盤(各消耗 200G 的容量),后來再加入的數據就只能寫入500G的磁盤中。此時的效能就變差了。
-
RAID-1(映像模式,mirror):完整備份
這種模式也是需要相同的磁盤容量,最好是一模一樣的磁盤。如果是不同容量的磁盤組成RAID-1時,那么總容量將以最小的那一顆磁盤為主!這種模式主要是讓同一份數據,完整的保存在兩個磁盤上。舉例說,如果有一個100MB的文件,有一個兩個磁盤組成的 RAID-1 時,那么這兩個磁盤將會同步寫入100MB到儲存空間去。因此,整體的RAID的同類幾乎少了 50%。 由於兩個磁盤的內容一樣,也成RAID-1 為 mirror 模式。
如上圖所示,一份數據傳送到 RAID-1 之后會分別寫入到各個磁盤里去。由於同一份數據會被分別寫入到其他不同磁盤,因此如果要寫入100MB時,數據傳送到I/O總線后會被復制多份到各個磁盤,結果就是數據量感覺變大了,因此在大量寫入 RAID-1 的情況下,寫入的效能可能會變得非常差。如果使用的是硬件RAID(磁盤陣列卡)時,磁盤陣列卡會主動的復制一份而不使用系統的 I/O 總線,效能方面則還可以。如果使用軟件磁盤陣列,可能效能就不好了。
由於兩個磁盤內的數據一模一樣,所以任何一顆磁盤損壞時,資料還是可以完整保留下來的。RAID-1 最大的優點大概在於數據的備份,不過由於磁盤容量有一半用在備份,因此總容量會是全部磁盤容量的一半而已。RAID-1的寫入效能不佳,讀取的效能還可以,因為數據有兩份在不同的磁盤商量,多個processes 在讀取同一筆數據時,RAID會自行取得最佳的讀取平衡。
-
RAID 1+0,RAID 0+1
RAID-0 效能佳但是數據不安全,RAID-1 數據安全但是效能不佳,能不能將兩者整合起來設定 RAID 呢? 由此引出 RAID-0 、RAID-1。
所謂RAID 1+0 就是:
(1)先讓兩個磁盤組成RAID-1,並且這樣的設定有兩組
(2)將這兩組RAID-1,再組成一組RAID-0.
以上就是 RAID 1+0,反過來就是 RAID 0+1
如上圖所示,Disk A + Disk B組成第一組 RAID 1,Disk C + Disk D組成第二組RAID 1,然后這兩組再整合成為一組 RAID 0。如果我有 100MB 的數據要寫入,由於RAID 0的關系,兩組RAID 1都會寫入50MB,又由於 RAID 1的關系,每個磁盤都會寫入50MB,如此一來,不論哪一組 RAID 1的磁盤損毀,由於是RAID1的影響數據,因此不會有任何問題發送,這也是目前儲存設備廠商最推薦的方法。
-
RAID-5
RAID-5 至少需要三顆以上的磁盤才能夠組成這種類型的磁盤陣列。這種磁盤陣列的數據寫入有點類似 RAID-0 ,不過每個循環的寫入過程中(striping),在每個磁盤還加入一個同位檢查數據(Parity),這個數據會記錄其他磁盤的備份數據,用於當有磁盤損壞時的救援。圖示如下
如上圖所示,每個循環寫入時,都會有部分的同位檢查碼(Parity)被記錄起來,並且記錄的同位檢查碼都記錄在不同的磁盤,因此,任何一個磁盤損毀時都能夠藉由其他磁盤的健康碼來重建原本磁盤內的數據。需要注意的是,由於有同位檢查碼,因此RAID5的總容量會是整體磁盤數量減一顆。RAID-5 僅能支持一個磁盤損毀的情況。RAID-6用兩個磁盤做為 Parity 的存儲,整體允許兩個磁盤損毀,也可以保證數據沒問題。
-
Spare Disk: 預備磁盤的功能:
當磁盤陣列的磁盤損毀時們就要將壞掉的磁盤拔除,然后換一個新的磁盤。換成新磁盤並且順利啟動磁盤陣列后,磁盤陣列就會開始主動的重建(rebuild)原本壞掉的那顆磁盤數據到新的磁盤上,然后磁盤陣列上面的數據就復原了,這是磁盤陣列的有點。不過還是需要動手拔插硬盤,除非系統支持拔插,否則通常得要關機才能這么做。
為了讓系統可以實時的在壞掉硬盤時主動的重建,因此就需要預備磁盤(spare disk) 的輔助。所謂的spare disk 就是一個或多個沒有包含在原本磁盤陣列等級中的磁盤,這個磁盤平時並不會被磁盤陣列所使用。當磁盤陣列有任何磁盤損壞時,則這個spare disk 會被主動的拉進磁盤陣列中,若磁盤陣列支持熱拔插,直接將壞掉的那個磁盤換一個新的,再將那個新的設定為spare disk ,就完成了
-
磁盤陣列的優點
- 數據安全與可靠性:磁盤損毀時,數據是否還能夠安全的救援或使用
- 讀寫效能:例如RAID 0 可以加強讀寫效能,讓系統I/O部分得以改善
- 容量:可以讓多顆磁盤組合起來,故單一文件系統可以有相當大的容量
1.2 software,hardware RAID
硬件磁盤陣列是透過磁盤陣列卡來達成數組的目的。磁盤陣列卡上有一塊專門的芯片在處理RAID的任務,因此在效能方面會比較好,在很多任務磁盤陣列不會消耗本系統的 I/O 總線,理論上效能會較佳。此外目前一般的高階磁盤陣列卡都支持熱拔插,不關機的情況下抽換損壞的磁盤,對於系統的復原與數據的可靠性方面非常的好用。
軟件磁盤陣列主要是透過軟件來仿真數組的任務,因此會損耗較多的系統資源,比如說CPU的運算與 I/O總線的資源等
CentOS 提供的軟件磁盤陣列為 mdadm 這套軟件,這套軟件會以 partition 或 disk 為磁盤的單位,也就是說,不需要兩個以上的磁盤,只要有兩個以上的分區槽(partition)就能夠設計磁盤陣列。mdadm 支持前面提到的 RAID0/1/5/spare disk等。而且提供的管理機制可以達到類似熱拔插的功能,可以在線進行分區槽的抽換。
硬件磁盤陣列在Linux底下看起來是一個實際的大磁盤,硬件磁盤陣列的裝置文件名為 /dev/sd[a-p] ,因為使用到SCSI的模塊。
軟件磁盤陣列是系統仿真的,使用的裝置文件名是系統的裝置文件,文件名為/dev/md0,/dev/md1 兩者的裝置文件名不相同
1.3 軟件磁盤陣列的設定
演示環境:kylin:release V10 (SP1) /(Tercel)-x86_64-Build19/20210319
軟件磁盤陣列的設定需要使用指令mdadm,raid的語法大概如下
[root@localhost ~]# mdadm --detail /dev/md0
[root@localhost ~]# mdadm --create /dev/md[0-9] --auto=yes --level=[015] --chunk=NK --raid-devices=N --spare-devices=N /dev/sdx /dev/sdx
選項與參數:
--create : 建立RAID選項
--auto=yes : 決定建立后面接的軟件磁盤陣列裝置
--chunk=NK : 決定這個裝置的chunk大小,一般是64K 或512K
--raid-devices=N: 使用幾個磁盤(partition) 作為磁盤陣列的裝置
--spare-devices=N: 使用幾個磁盤作為備用(spare)裝置
--level=[015] : 設定這組磁盤陣列的等級。支持很多,建議使用 0 1 5 即可
--detail : 后面所接的磁盤裝置的詳細信息
以上語法中,最后面會接許多的裝置文件名,這些裝置文件名可以是整個磁盤,例如/dev/sdb,也可以使分區槽,例如 /dev/sdb1之類的。不過,這些裝置文件名的總數必須要等於 --raid-devices 與 --spare-devices 的個數總和才行。
1.3.1 建立 RAID5 :
RAID5環境:
- 4個partition 組成RAID 5;
- 每個 partition 約為 1G
- 利用一個partition 設定為spare disk
- chunk 設定為256k
- spare disk 大小與其他 RAID 所需的 partition 一樣
- 此 RAID 5 掛載到 /srv/raid目錄下
首先先建好分區:
sdb13567 為五個partition
以mdadm 建立 RAID
[root@localhost ~]# mdadm --create /dev/md0 --auto=yes --level=5 --chunk=256K --raid-devices=4 --spare-devices=1 /dev/sdb1 /dev/sdb3 /dev/sdb5 /dev/sdb6 /dev/sdb7
mdadm: Defaulting to version 1.2 metadata
mdadm: array /dev/md0 started.
[root@localhost ~]# mdadm --detail /dev/md0
/dev/md0:
Version : 1.2
Creation Time : Wed Sep 8 18:25:42 2021
Raid Level : raid5
Array Size : 3139584 (2.99 GiB 3.21 GB)
Used Dev Size : 1046528 (1022.00 MiB 1071.64 MB)
Raid Devices : 4
Total Devices : 5
Persistence : Superblock is persistent
Update Time : Wed Sep 8 18:25:50 2021
State : clean
Active Devices : 4
Working Devices : 5
Failed Devices : 0
Spare Devices : 1
Layout : left-symmetric
Chunk Size : 256K
Consistency Policy : resync
Name : localhost.localdomain:0 (local to host localhost.localdomain)
UUID : 4e7b3d01:2e6ff0f6:9743a623:0f7fa446
Events : 18
Number Major Minor RaidDevice State
0 8 17 0 active sync /dev/sdb1
1 8 19 1 active sync /dev/sdb3
2 8 21 2 active sync /dev/sdb5
5 8 22 3 active sync /dev/sdb6
4 8 23 - spare /dev/sdb7
也可以用以下命令查看系統軟件磁盤陣列的情況:
[root@localhost ~]# cat /proc/mdstat
Personalities : [raid6] [raid5] [raid4]
md0 : active raid5 sdb6[5] sdb7[4](S) sdb5[2] sdb3[1] sdb1[0]
3139584 blocks super 1.2 level 5, 256k chunk, algorithm 2 [4/4] [UUUU]
unused devices: <none>
1.3.2 格式化與掛載使用RAID
參數情況
-
stripe(chunk)容量為256K,所以 su = 256k
-
共有 4 個part組成 RAID5,因此容量少一個,sw=3
-
由上面兩項計算出數據寬度為: 256K*3=768K
整體來講,優化這個XFS 文件系統如下:
[root@localhost ~]# mkfs.xfs -f -d su=256k,sw=3 -r extsize=768k /dev/md0 meta-data=/dev/md0 isize=512 agcount=8, agsize=98048 blks = sectsz=512 attr=2, projid32bit=1 = crc=1 finobt=1, sparse=1, rmapbt=0 = reflink=1 data = bsize=4096 blocks=784384, imaxpct=25 = sunit=64 swidth=192 blks naming =version 2 bsize=4096 ascii-ci=0, ftype=1 log =internal log bsize=4096 blocks=5184, version=2 = sectsz=512 sunit=64 blks, lazy-count=1 realtime =none extsz=786432 blocks=0, rtextents=0 [root@localhost ~]# mkdir /srv/raid [root@localhost ~]# mount /dev/md0 /srv/raid [root@localhost ~]# df -Th /srv/raid/ 文件系統 類型 容量 已用 可用 已用% 掛載點 /dev/md0 xfs 3.0G 54M 3.0G 2% /srv/raid
1.4 仿真RAID錯誤的救援模式
相關語法:
[root@localhost ~]# mdadm --manage /dev/md0[0-9] [--add 裝置] [--remove 裝置] [--fail 裝置]
--add: 會將后面的裝置加入到這個md中
--remove: 會將后面的裝置從這個md中移除
--fail: 會將后面的裝置設定成為出錯的狀態
1.4.1 設定磁盤為錯誤 (fault)
首先,先處理一下,該如何讓一個磁盤變成錯誤,然后讓 spare disk 自動開始重建系統
# 0.復制一些文件到/srv/raid 中,模擬RAID已經在使用
[root@localhost ~]# cp -a /etc /var/log /srv/raid
[root@localhost ~]# df -Th /srv/raid/; du -sm /srv/raid/*
文件系統 類型 容量 已用 可用 已用% 掛載點
/dev/md0 xfs 3.0G 96M 2.9G 4% /srv/raid
28 /srv/raid/etc
7 /srv/raid/log
# 1.設定/sdb/sdb3裝置出錯
[root@localhost ~]# mdadm --manage /dev/md0 --fail /dev/sdb3
mdadm: set /dev/sdb3 faulty in /dev/md0
[root@localhost ~]# mdadm --detail /dev/md0
/dev/md0:
Version : 1.2
Creation Time : Wed Sep 8 18:25:42 2021
Raid Level : raid5
Array Size : 3139584 (2.99 GiB 3.21 GB)
Used Dev Size : 1046528 (1022.00 MiB 1071.64 MB)
Raid Devices : 4
Total Devices : 5
Persistence : Superblock is persistent
Update Time : Wed Sep 8 18:49:43 2021
State : clean
Active Devices : 4
Working Devices : 4
Failed Devices : 1
Spare Devices : 0
Layout : left-symmetric
Chunk Size : 256K
Consistency Policy : resync
Name : localhost.localdomain:0 (local to host localhost.localdomain)
UUID : 4e7b3d01:2e6ff0f6:9743a623:0f7fa446
Events : 37
Number Major Minor RaidDevice State
0 8 17 0 active sync /dev/sdb1
4 8 23 1 active sync /dev/sdb7
2 8 21 2 active sync /dev/sdb5
5 8 22 3 active sync /dev/sdb6
1 8 19 - faulty /dev/sdb3
可以看到 /dev/sdb3 出錯了,spare disk 已經在使用中了
1.4.2 將出錯的磁盤移除並加入新磁盤
- 先從/dev/md0 數組中移除 /dev/sdb3 這個(磁盤)
- 整個Linux 系統關機,拔除 /dev/sdb3 這個(磁盤),並安裝上新的 /dev/sdb3(磁盤),之后開機
- 將新的 /dev/sdb3 放入到 /dev/md0 數組中
# 3. 拔除舊的 /dev/sdb3 磁盤
[root@localhost ~]# mdadm --manage /dev/md0 --remove /dev/sdb3
mdadm: hot removed /dev/sdb3 from /dev/md0
# 4. 安裝新的 /dev/sdb3 磁盤
[root@localhost ~]# mdadm --manage /dev/md0 --add /dev/sdb3
mdadm: added /dev/sdb3
[root@localhost ~]# mdadm --detail /dev/md0
/dev/md0:
Version : 1.2
Creation Time : Wed Sep 8 18:25:42 2021
Raid Level : raid5
Array Size : 3139584 (2.99 GiB 3.21 GB)
Used Dev Size : 1046528 (1022.00 MiB 1071.64 MB)
Raid Devices : 4
Total Devices : 5
Persistence : Superblock is persistent
Update Time : Wed Sep 8 18:58:08 2021
State : clean
Active Devices : 4
Working Devices : 5
Failed Devices : 0
Spare Devices : 1
Layout : left-symmetric
Chunk Size : 256K
Consistency Policy : resync
Name : localhost.localdomain:0 (local to host localhost.localdomain)
UUID : 4e7b3d01:2e6ff0f6:9743a623:0f7fa446
Events : 39
Number Major Minor RaidDevice State
0 8 17 0 active sync /dev/sdb1
4 8 23 1 active sync /dev/sdb7
2 8 21 2 active sync /dev/sdb5
5 8 22 3 active sync /dev/sdb6
6 8 19 - spare /dev/sdb3
可以看到/dev/sdb3 的狀態編程了 spare
1.5 開機自啟動 RAID 並自動掛載
新的distribution 大多會自己搜尋 /dev/md[0-9] 然后在開機的時候給予設定好所需要的功能,不過建議還是修改一下配置文件。software RAID的配置文件在/etc/mdadm.conf
,只需要知道 /dev/md0的UUID就能夠設定這個文件。
# 查看UUID
[root@localhost ~]# mdadm --detail /dev/md0 | grep -i uuid
UUID : 4e7b3d01:2e6ff0f6:9743a623:0f7fa446
# 設定mdadm.conf
[root@localhost ~]# vim /etc/mdadm.conf
ARRAY /dev/md0 UUID=4e7b3d01:2e6ff0f6:9743a623:0f7fa446
# 開始設定開機自動掛載並測試
[root@localhost ~]# blkid /dev/md0
/dev/md0: UUID="7c3c9a5e-2e3f-4b3a-91e9-b3031600b2d5" BLOCK_SIZE="512" TYPE="xfs"
[root@localhost ~]# echo "UUID=7c3c9a5e-2e3f-4b3a-91e9-b3031600b2d5 /srv/raid xfs defaults 0 0" >> /etc/fstab
[root@localhost ~]# umount /dev/md0 ; mount -a
[root@localhost ~]# df -Th /srv/raid/
文件系統 類型 容量 已用 可用 已用% 掛載點
/dev/md0 xfs 3.0G 90M 2.9G 3% /srv/raid
# 要確定可以順利掛載,並且沒有發生任何錯誤
重啟系統測試;
1.6 關閉軟件 RAID(重要)
如果不使用這個/dev/md0
,需要關掉RAID,如果只是將/dev/md0卸除,然后忘記將RAID關閉,在未來重新分區/dev/sdbX時,可能出現一些莫名的錯誤狀況,所以需要關閉RAID。以下是關閉步驟。
# 1.卸載且刪除配置文件內與 /dev/md0有關的設定
[root@localhost ~]# umount /srv/raid
[root@localhost ~]# vim /etc/fstab
****
# 2. 覆蓋掉 RAID 的 metadata 以及 XFS 的superblock
[root@localhost ~]# dd if=/dev/zero of=/dev/md0 bs=1M count=50
記錄了50+0 的讀入
記錄了50+0 的寫出
52428800字節(52 MB,50 MiB)已復制,0.174493 s,300 MB/s
[root@localhost ~]# mdadm --stop /dev/md0
mdadm: stopped /dev/md0
# 以上就關閉了
[root@localhost ~]# dd if=/dev/zero of=/dev/sdb1 bs=1M
[root@localhost ~]# dd if=/dev/zero of=/dev/sdb3 bs=1M
[root@localhost ~]# dd if=/dev/zero of=/dev/sdb5 bs=1M
[root@localhost ~]# dd if=/dev/zero of=/dev/sdb6 bs=1M
[root@localhost ~]# dd if=/dev/zero of=/dev/sdb7 bs=1M
# 查看狀態 確實關閉了
[root@localhost ~]# cat /proc/mdstat
Personalities : [raid6] [raid5] [raid4]
unused devices: <none>
[root@localhost ~]# vim /etc/mdadm.conf
# 注釋掉內容或刪掉
RAID的相關數據會存一份在磁盤中,只是將配置文件移除,同時關閉RAID,但是分區槽並沒有重新規划過,那么重新啟動過后,系統還是會將這個RAID建立起來,只是名稱會變成 /dev/md127,因此移除掉 software RAID時,上述的dd指令要執行,也不要dd到錯誤的磁盤。
本次模擬raid-5,采用的一個磁盤中的不同part,實際使用中最好還是使用不同的磁盤,才能使用到不同磁盤的讀寫,效能才更好,磁盤損壞時也能從其他磁盤挽救回來。
參考:
[1] 鳥哥.鳥哥的Linux私房菜[M]