圖 1 描述的是一個未經條帶化處理的連續數據的分布,圖 2 描述的是一個已經被條帶化處理的連續數據的分布,從中比較,我們可以發現圖 2 中對連續數據的讀寫都有最大的並發能力。
圖 1. 未經條帶化處理的連續數據
圖 2. 已經被條帶化處理的連續數據
由於條帶化在 I/O 性能問題上的優越表現,以致於在應用系統所在的計算環境中的多個層次或平台都涉及到了條帶化的技術,如操作系統和存儲系統這兩個層次中都可能使用條帶化技術。下圖展示了這兩個層次的 I/O 結構。
圖 3.操作系統和存儲系統兩個層次的 I/O 結構
在操作系統的層次中,我們可以使用軟件條帶(如 LVM 中 LV 的條帶來實現條帶化技術)或硬件條帶(如各種 RAID)。在存儲系統層次中,目前市場上絕大部分產品都提供了各種各樣的條帶技術(如各種 RAID)。
條帶化的設置
當使用 LVM 或者硬件條帶化時,決定條帶化效果的因素是條帶深度(stripe depth)和條帶寬度(stripe width):
條帶深度指的是條帶塊的大小,也叫條帶單元;
條帶寬度指的是條帶深度的產量或者一個條帶分布的驅動數;
需要根據系統的 I/O 要求來合理的選擇這些設置。對於數據庫系統來說,比較合理的條帶深度是從 256K 到 1M 。下面分析一下條帶深度和條帶寬度的影響因素。
條帶深度
為了提高 I/O 效率,一次邏輯 I/O 請求轉化成物理 I/O 請求後,應該讓這些物理 I/O 分布到最多的物理磁盤上去,也就是每個物理磁盤處理的物理 I/O 最少,最好只有一次 , 因而影響條帶的一個重要因素就是一次邏輯 I/O 請求的大小。
此外,系統中 I/O 的並發度不同我們對條帶的配置要求也不同。例如,在高並發度且邏輯 I/O 請求的大小都比較小的情況下,我們希望一塊磁盤能同時響應多個 I/O 請求;而在那些存在大的邏輯 I/O 請求的低並發度系統中,我們可能就需要多塊磁盤同時響應一個 I/O 請求。無論是一個磁盤還是多個磁盤響應 I/O 請求,我們的一個原則是讓一次邏輯 I/O 能被物理設備一次處理完成。
條帶寬度
正如我們前面所述,無論是一個還是多個磁盤響應一個邏輯 I/O,我們都希望物理設備只處理一次 I/O 。因而在確定了條帶深度的基礎上,我們需要保證條帶寬度 >= I/O 請求的大小 / 條帶深度。這樣就能最大程度的保證 I/O 請求的並發處理能力了。
此外,考慮到以後系統容量的擴充,我們也需要規劃好條帶寬度。
在 DB2 中合理規劃和設置條帶相關參數
下面先看下影響 I/O 性能 DB2 數據庫的相關參數:
頁大小(page size):DB2 中的數據頁大小,也決定了 DB2 一次單個 I/O 請求中的數據塊的大小;
預讀大小(prefetch size):在預取讀時,一次讀取數據塊的數量不能大於操作系統的最大 I/O 大小(Oracle 中是參數 block size);
排序堆(sortheap)和排序堆阈值(sheapthres) :內存中 sort 區域的大小,也決定了並發排序操作時的 I/O 大小;
其中,前面兩個是最關鍵的兩個參數。
DB2 的數據頁大小是在創建數據庫的時候指定的,並且不能被動態的修改。它決定了在 DB2 中所有的表空間默認的頁大小。但是我們在創建每個表空間的時候還可以根據數據存儲的需要單獨指定頁的大小。
在 OLTP 系統中,會存在大量小的並發的 I/O 請求。這時就需要考慮選擇比較大的條帶深度。使條帶深度大於 I/O 大小就稱為粗粒度條帶(Coarse Grain Striping)。在高並行度系統中,條帶深度為(n * page size),其中 n 為大於 1 的整數。通過粗粒度條帶能實現最大的 I/O 吞吐量(一次物理 I/O 可以同時響應多個並發的邏輯 I/O)。大的條帶深度能夠使像全表掃描那樣的預取讀操作由一個磁盤驅動來響應,並提高預取讀操作的性能。在 OLTP 系統中,為了避免一個邏輯 I/O 請求被多個物理 I/O 操作完成,條帶深度就需要設置為兩倍或者兩倍以上於 DB2 頁大小。例如,如果條帶深度是物理 I/O 大小的 N 倍,對於大量並發 I/O 請求,我們可以保證最少有(N-1)/ N 的請求是由一塊磁盤來完成。
在低並發度的 DSS 系統中,由於 I/O 請求一般是序列化的,為了避免出現 I/O 集中的熱點磁盤,我們需要避免邏輯 I/O 只有一塊磁盤處理。這時粗粒度條帶就不適合了。我們應該選擇小的條帶深度,使一個邏輯 I/O 分布到多個磁盤上,從而實現 I/O 的負載均衡。這就叫細粒度條帶。條帶深度的大小必須為(n * page size),其中 n 為小於預取參數(prefetch size)大小的整數。
預取大小也是對條帶化有影響的一個重要參數,它決定了 DB2 異步 I/O 的基本單位。首先我們要知道 DB2 的預取(prefetching)I/O 機制,在數據庫普遍存在著大量、連續的 I/O 時候,預取可以極大的提高數據庫數據讀取的 I/O 性能(例如 DSS 系統)。
圖 4 展示了 DB2 數據庫的預取處理流程。
圖 4.DB2 預取處理
上圖中,我們發現,用戶在獲得 DB2 中的數據時有一個比較復雜的 I/O 處理過程:用戶向數據庫發出請求; DB2 異步的處理 I/O ;將請求提交給 I/O Server ;以預取大小為單位從存儲中讀取數據;在內存中處理數據;最後將請求的結果返回給用戶。在這麼多步驟的處理中,我們很明顯的發現,訪問物理存儲的工作是由 I/O Server 以預取大小為單位實現的。所以在上述的過程中,在 DB2 數據庫級別影響單次物理 I/O 最重要的因素就是預取大小。為了提高 I/O 的性能,就需要在設置 DB2 預取大小時必須與條帶深度和條帶寬度有較好的匹配。
首選要保證的就是預取的大小必須是條帶深度的整數倍,其次預取大小最好是條帶深度與條帶寬度乘積的整數倍(當然預取大小還與 DB2 的其他參數有關,如 page size、extent size、容器數量等等,這裡不一一討論)。這樣就可以使預取時候所執行的物理 I/O 被均衡的分布所有的物理存儲中。
另外,I/O 過程中,你無法保證 DB2 數據庫的頁的邊界能與條帶單元的大小對齊。如果條帶深度大小和 DB2 的頁大小完全相同,而它們的邊界沒有對齊的話,那麼就會存在大量的一個單獨的小的 I/O 請求在兩塊磁盤上完成。
如今大多數 LVM 都支持在線動態增加磁盤。也就是在磁盤容量不足時,我們可以隨時將新磁盤加入到一個已經使用的邏輯卷中。這樣的話,我們在設置邏輯卷時就可以簡單地將所有磁盤都歸入到一個卷中去。
如果你的條帶寬度設置得比較小,就需要估算出你的各個數據庫表空間容器的 I/O 負載,並根據負載量不同將他們分別部署到不同卷上一分擔 I/O 負載。
在 AIX 中合理規劃和設置條帶相關參數
操作系統最大 I/O 大小:決定了一次單個的 I/O 請求的大小上限,不同的操作系統有不同的參數,AIX 系統是卷組的 LTG(Logical Track Group)參數(HP-UX 是參數 max_I/O_size);
操作系統級別條帶化的設置;
操作系統最大的 I/O 大小對條帶化深度的設置也產生著重要的影響。當邏輯 I/O 請求達到操作系統之後,如果邏輯 I/O 的大小超過了操作系統能處理最大的 I/O 大小,操作系統會根據自己能夠處理的最大的 I/O 大小來分割邏輯 I/O 請求。在 AIX 中,這個參數就是 LTG,也就是當邏輯 I/O 的大小超過了所在卷組的 LTG 的設置之後,AIX 會將邏輯 I/O 以 LTG 為單位進行分割之後,才會將分割好的 I/O 請求分發到物理存儲中去。所以 LTG 的大小應該與條帶深度大小相同或者是條帶深度大小的整數倍。
在 AIX V5.3 後,卷組的 LTG 參數是在 varyonvg 的時候指定的,語法如下:
varyonvg – M 512K vgname
上面的語句將卷組“ vgname ”的 LTG 參數設置為 512K,每次在 varyonvg 卷組的時候可以設置不同的 LTG(在 AIX5.3 之前,LTG 是在創建卷組的時候設置,並且不能修改)。目前 LTG 的取值范圍為:4K、8K、16K、32K、64K、128K、1M、2M、4M、8M、16M、32M 和 128M 。而且如果卷組中 PV 不能支持 LTG 的設置 varyonvg 命令將會失敗。
很多操作系統支持操作系統級別的條帶化(而不是存儲系統提供的條帶化),這個條帶技術原理與之前介紹的無異。操作系統級別的條帶化又分為邏輯條帶化和物理條帶化兩種技術。邏輯條帶化通常是通過 LVM 在 LV 級別實現的,而物理條帶化通常是通過操作系統機器上的硬件實現的。在這裡介紹一下 AIX 操作系統中 LVM 實現的邏輯條帶化技術。
AIX 系統中 LVM 的基本結構如下圖所示。
圖 5.AIX 中的 LVM 結構
首先在 AIX 系統創建 PV,再由一個或多個 PV 創建 VG,在 VG 之上再創建 LV,所以 LV 中的邏輯存儲最終會映射到 PV 上的物理存儲中。在不使用條帶技術的情況下,LV 上連續的數據塊會以圖 1 方式分布在 PV 之上。
在使用條帶技術之後,LV 上連續的數據塊就會以圖 2 的方式分散的分布在這些 PV 之上了。
這樣在對 LV 上連續的數據進行讀和寫的時候,就可以實現同時在多個 PV 上並行的處理 I/O 請求了,從而可以極大的提高 I/O 的性能。
上面已經提到的關於條帶深度和條帶寬度的特點在 LV 上同樣適用。只是條帶化處理的 I/O 不是發送到物理磁盤上,而是發送到了 PV 上。在操作系統最簡單的存儲方案中,一個 PV 對應的就是一個物理磁盤,而現在普遍使用了單獨的存儲系統之後,一個 PV 通常只是一個邏輯磁盤,而這個邏輯磁盤通常又是以某種條帶化技術映射到了存儲系統中的多個物理磁盤上。所以在操作系統中使用了 LV 級別的條帶化之後,一定要保證操作系統中條帶的設置與存儲系統中的條帶設置相匹配,否則性能將無法得到保證。
那麼我們是否需要在使用了存儲系統條帶技術的同時再使用操作系統級別的條帶技術呢?答案是:不一定。條帶化技術的目的就是為了最大限度的將 I/O 負載均衡,實現最大化的 I/O 並行處理。只要有利於這個目標,我們就可以同時這兩個不同層次的條帶化,而相反的,如果同時使用了這兩個層次的條帶化後並沒有實現更好的 I/O 性能,那麼就沒有必要了,因為這更增加了 I/O 結構的復雜性,更不利於存儲空間的管理。
在使用了單獨的存儲系統之後,操作系統級別的條帶化帶給我們最大的性能優勢就是 LV 上的 I/O 可以在多個 PV 上並行執行,而每個 PV 又映射到不同的一組的物理磁盤上,這樣就可以將 LV 上的 I/O 分布在更多的物理磁盤上,這樣對提高 I/O 的性能有極大的幫助。如果 LV 分布的多個 PV 都映射到同一組的物理磁盤上,則對 I/O 性能的提高幫助不大。
在使用了操作系統級別的條帶化之後,還需要重點考慮的就是條帶深度,操作系統級別條帶深度的大小決定了在向 PV 發送 I/O 的大小,為了獲得最好的性能,就要進一步的分析 Pv 在映射到存儲系統時條帶深度的設置,最好的結果就是:操作系統條帶深度 = 存儲系統條帶深度×存儲系統條帶寬度,這樣就能最大限度的保證兩個層次條帶深度的匹配,從而有最好的 I/O 性能。
在操作系統中設置條帶化的時候,注意下面的原則:
操作系統的條帶塊的大小設置的大些,應該是硬件條帶塊大小的整數倍。
操作系統的條帶的范圍減小。
必須和應用的特點相結合(例如:應用是隨機讀還是連續讀),條帶技術對大量的順序讀 / 寫有最好的 I/O 性能。
總結
條帶化技術到目前為止依然是提高 I/O 性能最好的一種技術,它通過最大化的 I/O 並行特性發揮了所有可以利用的硬件的能力。所以條帶化技術各種環境中都得到了廣泛的應用。我們在考慮性能問題的時候不可錯過對條帶化技術的關注。