分區與命名規範
OSS按照檔案名UTF-8編碼的順序對用戶數據進行自動分區,從而能夠處理海量檔案,以及承載高速率的客戶請求。不過,如果客戶在上傳大量對象時,在命名上使用了順序首碼(如時間戳記或字母順序),可能會導致大量檔案索引集中儲存於某個特定分區。這樣,當用戶的請求速率超過2000操作/秒時(下載、上傳、刪除、拷貝、獲取元數據資訊等操作算1次操作,大量刪除N個檔案、列舉N個檔案等操作算N次操作),會帶來如下後果:
- 該分區成為熱點分區,導致分區的I/O能力被耗盡,或被系統自動限制請求速率。
- 熱點分區的存在會觸發系統進行持續的分區數據再均衡,這個過程可能會延長請求處理時間。
從而降低OSS的水平擴充效果,導致客戶的請求速率受限。
要解決這個問題,根本上,要消除檔案名中的順序首碼。我們可以在檔案名首碼中引入某種隨機性,這樣檔案索引(以及 I/O 負載)就會均勻分布在多個分區。
下面提供了幾個將順序首碼改為隨機性首碼的方法案例。
- 樣本 1:向檔案名添加十六進位雜湊首碼
如下例所示,用戶使用了日期與客戶ID組建檔案名,包含了順序時間戳記首碼:
sample-bucket-01/2017-11-11/customer-1/file1 sample-bucket-01/2017-11-11/customer-2/file2 sample-bucket-01/2017-11-11/customer-3/file3 ... sample-bucket-01/2017-11-12/customer-2/file4 sample-bucket-01/2017-11-12/customer-5/file5 sample-bucket-01/2017-11-12/customer-7/file6 ...
針對這種情況,我們可以對客戶ID計算雜湊,即MD5 (customer-id),並取若干字元的雜湊首碼作為檔案名的首碼。假如取4個字元的雜湊首碼,結果如下所示:
sample-bucket-01/2c99/2017-11-11/customer-1/file1 sample-bucket-01/7a01/2017-11-11/customer-2/file2 sample-bucket-01/1dbd/2017-11-11/customer-3/file3 ... sample-bucket-01/7a01/2017-11-12/customer-2/file4 sample-bucket-01/b1fc/2017-11-12/customer-5/file5 sample-bucket-01/2bb7/2017-11-12/customer-7/file6 ...
加入4個字元組成的十六進位雜湊作為首碼,每個字元有0-f共16種取值,因此4個字元共有16^4=65536種可能的字元組合。那麼在儲存系統中,這些數據理論上會被持續劃分至最多65536個分區,以每個分區2000操作/秒的性能瓶頸標準,再結合您的業務的請求速率,以此您可以評估hash桶的個數是否合適。
如果您想要列出檔案名中帶有特定日期的檔案,例如列出sample-bucket-01裡帶有2017-11-11的檔案,您只要對sample-bucket-01進行列舉(即通過多次調用List Object介面,分批次地獲得sample-bucket-01下的所有檔案),然後合并帶有該日期的檔案即可。
- 樣本 2:反轉檔案名
如下例所示,用戶使用了毫秒精度的UNIX時間戳記組建檔案名,同樣屬於順序首碼:
sample-bucket-02/1513160001245.log sample-bucket-02/1513160001722.log sample-bucket-02/1513160001836.log sample-bucket-02/1513160001956.log ... sample-bucket-02/1513160002153.log sample-bucket-02/1513160002556.log sample-bucket-02/1513160002859.log ...
由前面的分析,我們知道,這種順序首碼命名,在請求速率超過一定閾值時,會引發性能問題。我們可以通過反轉時間戳記首碼來避免,這樣檔案名就不包含順序首碼了。反轉後結果如下:
sample-bucket-02/5421000613151.log sample-bucket-02/2271000613151.log sample-bucket-02/6381000613151.log sample-bucket-02/6591000613151.log ... sample-bucket-02/3512000613151.log sample-bucket-02/6552000613151.log sample-bucket-02/9582000613151.log ...
由於檔案名中的前3位元字代表毫秒時間,會有1000種取值。而第4位元字,每1秒鐘就會改變一次。同理第5位元字每10秒鐘就會改變一次…以此類推,反轉檔案名後,極大地增強了首碼的隨機性,從而將負載壓力均勻地分攤在各個分區上,避免出現性能瓶頸。