簡介
我們都聽說過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秒/磁軌定址時間+旋轉延遲。
我們來看如下例子:
HP 300GB 15k SAS drive(200刀) | |
轉速 | 15000 |
平均磁軌定址時間 | 2.9ms |
平均旋轉延遲 | 1.83ms |
我們可以用公式計算IOPS了:
IOPS = 1/(2.9ms + 1.83ms)
= 1/(4.73ms)
= 1/(0.00473)
= 211 IOPS
我們可以看到,這個磁碟的IOPS為211(並不是很慘)。
假如我們想要節省更多的錢,我們再來看一個磁碟的例子以及和上面磁碟的區別:
HP 300GB 7200 SATA drive(100刀) | |
轉速 | 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 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
譯者注:關於文中可能對於細節有某些錯誤,已經有人在論壇指出,請看連結:檢視關於本篇文章的討論.但是文章對於RAID的系統性講述還是很到位的。