簡介
我們都聽說過RAID,也經常作為SQL DBA、開發人員或構架師在工作中討論RAID。但是,其實我們很多人都對RAID的原理,等級,以及RAID是如何影響SQL Server性能並不甚了解。
本篇文章就是為了補上這一課。
磁盤構架
今天的磁盤,和70年代45rpm(轉/分鍾)的唱片機很像(你還能記得嗎?),僅僅是一個有着軸(磁道)旋轉的媒體(面)並將數據存入稱之為扇區的磁盤段。
就像唱片機那樣,磁盤驅動器擁有一個擺臂來控制針(在這里可以稱之為”磁頭”)來訪問數據。但對於磁盤來說,並不像唱片機那樣只讀,而是既可以讀又可以寫。
為了從特定的扇區讀或者寫數據,磁盤必須進行旋轉然后擺臂移動使得磁頭移動到垂直於指定扇區的正上方以訪問數據。
這個過程就是基本的輸入/輸出操作的過程(I/O)。
IOPS
IOPS這個術語也是被經常拿出來裝X的,但同樣,對這個術語真正理解的人並不多。
很多人都明白IOPS是Input Output Operations per Second的縮寫,但是將這個定義轉換為實際的概念對於某些人就有點難了。
對IOPS基本的理解是對滿足特定輸入輸出請求的平均時間的一種衡量。
這里重點需要知道這個度量標准是基於讀取0字節的文件,這僅僅是為了統計和標准化的目的因為一個磁盤扇區大小並不同。
物理磁盤的限制
磁盤會有一些物理限制會限制磁盤能達到的IOP級別。這個限制是磁道尋址時間(seek time)和旋轉延遲(rotational latency)。
磁道尋址時間是為了使得磁頭可以移動到所要讀的扇區,移動擺臂所花費的平均時間。
旋轉延遲是為了使磁頭讀取盤面特定位置旋轉磁盤所話費的時間(通常為毫秒級)。
單位IOP所花的時間公式如下:
單位IOP時間=磁道尋址時間+旋轉延遲
所以,通過這個公式我們就可以輕松計算給定磁盤的最大IOPS。
而每秒的IOPS數字也是我們最感興趣的,公式如下:
1秒/磁道尋址時間+旋轉延遲。
我們來看如下例子:
|
|
轉速 | 15000 |
平均磁道尋址時間 | 2.9ms |
平均旋轉延遲 | 1.83ms |
我們可以用公式計算IOPS了:
IOPS = 1/(2.9ms + 1.83ms)
= 1/(4.73ms)
= 1/(0.00473)
= 211 IOPS
我們可以看到,這個磁盤的IOPS為211(並不是很慘)。
假如我們想要節省更多的錢,我們再來看一個磁盤的例子以及和上面磁盤的區別:
|
|
轉速 | 7200 |
平均磁道尋址時間 | 10ms |
平均旋轉延遲 | 2.1ms |
通過公式可以看到這個磁盤的最大IOPS:
IOPS = 1/(10ms + 2.1ms)
= 1/(12.1ms)
= 1/(0.0121)
= 82 IOPS
這個7200轉的磁盤的最大IOPS為82。
通過對比可以看到上面兩個磁盤的性能上的巨大差異,這也不難理解為什么同樣的容量價格會差這么多。
此外,文檔顯示如果你使用磁盤到其IOPS峰值,會產生請求隊列而造成延遲(一個在SQL Server中非常邪惡的詞匯,像躲避瘟疫一樣躲避它)。
而我看過的大多數文檔建議IOP保持在最大IOPS的80%左右。所以我們上面討論的第一個磁盤的最大IOPS是211如果服務於超過168的IOPS就會開始顯出延遲的征兆了。
現在我已經知道了單獨一個磁盤可以達到的IOPS數字,那么下一件事就是要滿足生產環境下的SQL Server實例需要多少IOPS?
我獲取這些數據僅僅通過在生產環境下查看PerfMon工具的physical disk: Disk Transfers/Sec 計數器。
這個數字是:
驅動 | 平均IOPS | 最大IOPS |
數據和索引 | 2313 | 16,164 |
日志 | 81.5 | 1,127 |
TempDB | 141 | 2,838 |
通過上面的數據看到,我們的快速磁盤僅僅能處理168的IOPS,所以結論是一個磁盤無論如何也無法滿足上面的IOPS要求。
所以解決這個問題的唯一辦法是使用某種機制來調整多個磁盤滿足上述需求。
如果我們有100個300GB 15k SAS驅動器,我們不僅獲得了30TB的存儲量,還獲得了16800的IOPS。
如果我們使用前面例子中較慢的磁盤,為了達到16800 IOPS,我們需要205塊這樣的驅動器,這使得我們需要比使用快速磁盤花更多的錢($20,000 vs $20,500),聽上去很諷刺,不是嗎?
RAID的必要性
現在,我們需要一堆磁盤來滿足我們的速度或是容量需求,所以我們需要某種機制來將工作負載加到多個磁盤,實現這個目的的主要手段就是RAID。
RAID代表"Redundant Array <of> Inexpensive Disks"(譯者注:這是最開始的定義,后來行業標准將I改為Independant,難道這是因為Inexpensive這個詞妨礙了他們收取更多的錢?),RAID提供了將一堆磁盤連接起來使得邏輯上變為1個的方法。
基於你如何串聯你的磁盤,RAID可以提供容錯性—當磁盤陣列中有一個磁盤崩潰時數據不會丟失。
此外,因為串聯了多個磁盤,我們可以消除單個磁盤的IOPS限制,更多的磁盤意味着更多的IOPS,就是這么簡單。
RAID級別
RAID只為了兩個目的:1)通過提高IOPS提高性能 2)提供容錯。更高的容錯性意味着更低的磁盤性能,同樣,高性能方案也會降低容錯性。
根據容錯性和性能的目標配置RAID就是所謂的RAID層級。RAID是對常用的RAID陣列的一種分裂,常見的RAID級別為:RAID0,RAID1,RAID5,RAID1+0,RAID0+1。
根據你對RAID級別的選擇,你需要付出所謂的”RAID代價”。某些RAID級別需要重復寫入兩次數據來保證容錯性,但這樣會犧牲性能。此外,因為重復寫入數據還需要更多的磁盤空間。RAID代價會大大提高你的RAID方案的成本。
為了明白RAID對於你的系統的影響和收益,熟悉常見的RAID級別和它們的實現原理變得非常重要。
RAID 0
第一個,也是最基本的RAID級別是RAID 0.RAID 0強調為了解決IO的限制而將數據寫入到磁盤陣列中。如果IO希望寫100MB的數據,RAID0會將100MB數據寫入到磁盤陣列的每個磁盤中。
這種方式大大減少了每個磁盤的負載,並且減少了旋轉延遲(每個磁盤不再需要轉和原來一樣的圈數就能滿足請求)。
雖然RAID0大大提高了IO性能,但沒有提供任何容錯措施,這意味着如果磁盤陣列中的某一塊磁盤崩潰,則整個磁盤陣列中的數據全部丟失。
因為RAID0並沒有提供任何容錯措施,所以在生產環境中RAID0幾乎不被使用。
還有一點值得注意的是,由於RAID0磁盤陣列中的每個磁盤都用於存儲數據,所以沒有任何磁盤空間的損失,比如使用RAID0,10個300GB的磁盤就會有3TB的可用存儲空間,這意味着沒有損失磁盤空間的RAID代價。
RAID 1
RAID1也被稱為”鏡像”,因為其通過一個鏡像磁盤來保證容錯性。在鏡像集中的每個磁盤都會有一個鏡像磁盤,RAID 1寫入的每一筆數據都會分別在兩個磁盤中各寫一份。這意味着任何一個磁盤除了問題,另一個磁盤就會頂上。用戶的角度來看並不知道出現了磁盤崩潰。
RAID 1需要付出寫入時的性能代價。每個寫入IOP需要運行兩次,但是對於讀來說卻會提升性能,因為RAID控制器對於大量數據請求會從兩個磁盤中讀取。
RAID 5
RAID 5也被稱為”Striping With Parity)”,這種方式既可以通過磁盤分割(Striping raid0)來提高性能,也可以通過奇偶性(Parity)來提供容錯,當一個磁盤崩潰后,奇偶數據可以通過計算重建丟失的數據。
雖然奇偶性是實現容錯的一種不錯的方式。但是從磁盤寫入來說代價高昂。也就是說對於每一個IOP寫請求,RAID5需要4個IOPS。
為什么需要這么高寫入代價的過程如下:
- 讀取原始數據(1 iop)
- 讀取當前奇偶數據(1 iop)
- 比較當前數據和新寫入請求
- 基於數據差異計算新的奇偶值
- 寫入新數據(1 iop)
- 寫入新的奇偶值(1 iop)
RAID 1+0
RAID 1+0 和其名字所示那樣,融合了RAID 0(磁盤分割)和RAID1(鏡像)。這種方式也被稱為:分割鏡像。
RAID 1+0 由於將數據分割到多個磁盤中使得並且不像RAID5那樣有奇偶效驗碼,所以寫入速度非常快。
但寫入速度還是會有影響因為需要重復寫入鏡像盤,但仍然,寫入速度還是非常的快。
而對於RAID 1+0 存儲的代價等同於RAID1 (鏡像),在RAID1+0中只有一半的磁盤空間可以用於存儲數據。
RAID 0+1
RAID 0+1 和RAID1 +0 是很像,它們都是通過磁盤分割和鏡像來實現目的。他們的區別更加學術化,這里我們假設他們一樣。
RAID 0+1和 RAID 1+0所付出的代價是一樣的。
其它RAID級別(2,3,4,6,DP等)
還有一些其它不常見的非標准RAID層級,RAID 2,3,4,6和RAID DP都和RAID5類似,他們都是通過分割和某種奇偶校驗來提供性能上和容錯。這些類似RAID 5的RAID層級的區別僅僅是它們如何寫入奇偶數據。它們之中有些是通過保留一個磁盤來存儲奇偶數據,還有一些是將奇偶數據分布到多個磁盤當中等等。如果需要,你可以去做這些研究,但對於我來說,我都稱它們為”RAID 5”
還有一個值得討論的非標准的RAID級別是RAID DP,DP的是”Dual Parity”的縮寫,這和RAID 5很像但其將奇偶數據寫入兩次,這對於寫入來說代價高昂,寫入代價被提高到了6(每一次IO寫請求需要6 IOPS)
RAID 比較
選擇合適的RAID層級並不容易,需要考慮多方面因素:成本,性能和容量。
下表總結了每個標准RAID層級的好處和壞處。
RAID Level | Fault Tolerance | Read Performance | Write Performance | RAID Write Penalty | Cost |
0 | None | Good | Excellent | 1 | Excellent |
1 | Good | Good | Good | 2 | Fair |
5 | Fair | Good | Poor | 4 | Good |
1+0 | Excellent | Excellent | Excellent | 2 | Poor |
DP | Good | Good | Terrible | 6 | Good |
SQL存儲推薦
SQL Server文件 | RAID級別 |
操作系統和SQL二進制文件 | RAID 1 |
數據和索引 | RAID 1+0 (如果預算不允許可以使用RAID 5) |
日志 | RAID 1+0 |
TempDB | RAID 1+0 |
備份 | RAID 5 |
其它考慮因素
當需要計划你的IO子系統和SQL文件分布以及RAID層級時,你需要多考慮其它因素。
RAID控制器
RAID可以通過2種方式實現:軟件實現和硬件實現。
在軟件RAID配置中,操作系統管理RAID級別以及多磁盤之間的IO負載。
在硬件RAID配置中,物理上會有一個硬件作為RAID控制器。
通常來說,硬盤RAID解決方案會更健壯,靈活和強大。根據你對RAID控制器的預算,你能獲得對應預算的配置選項。
比如,某些RAID控制器僅僅提供一個RAID層級(比如RAID5),一些更昂貴的RAID控制其提供了緩存功能。緩存可以用於緩存讀取操作,寫入操作以及它們兩者。更好的RAID控制器甚至提供了對於讀取和寫入分配緩存的百分比選項。
緩存對於SQL Server來說非常重要,尤其是對於寫來說。無論是何種RAID級別,都沒有讀取性能上的代價,所有的RAID層級都提高了讀取數據的速度。而寫入才是RAID的代價,你可以通過RAID緩存來緩存所有的寫入操作,這極大的提高了寫入性能。通常來說,有緩存的RAID控制器都帶有電池,這使得即使斷電,緩存的數據也不會丟失。
記住,SQL Server本身非常善於緩存讀取,所以使用昂貴的RAID控制器中的緩存來緩存讀取並沒有什么意義。
虛擬化
還有一個值得考慮的因素是虛擬化,無論你喜歡與否,我們已經步入了虛擬化的世界。在VMWare環境下部署生產環境下的SQL Server實例變得越來越普遍。
虛擬化也影響RAID和IO方面,根據你使用的虛擬化產品,當你選擇RAID級別時就需要考慮更多的因素,比如,VM是如何和存儲系統交互的。
總結
很明顯,我們還有一些信息沒有討論到,RAID對於SQL Server性能和容錯的重要性不言而喻。
我希望本篇文章能夠幫你理解RAID是如何影響你的SQL Server的性能。作為一個DBA或是數據庫構架師來說,你必須明白當前RAID配置有着怎樣的性能和容錯性。
參考資料
MSDN:
http://msdn.microsoft.com/en-us/library/ms190764.aspx
TechNet:
http://technet.microsoft.com/en-us/library/cc966534.aspx
Ed Whalen - PerfTuning.com
http://www.perftuning.com/files/pdf/RAID1.pdf
原文鏈接:http://www.sqlservercentral.com/articles/RAID/88945/
Translated by CareySon
譯者注:關於文中可能對於細節有某些錯誤,已經有人在論壇指出,請看鏈接:查看關於本篇文章的討論.但是文章對於RAID的系統性講述還是很到位的。