本文介紹利用阿里雲OSS分布式架構提升OSS資料處理速度、降低資料延遲、加速應用程式響應能力的多種方法,旨在最佳化OSS效能表現。
將順序首碼改為隨機性首碼
為了最佳化OSS的資料分布和提升處理效率,建議您採用隨機性首碼替代傳統的順序首碼來命名您的檔案。OSS根據檔案key的UTF-8編碼順序自動劃分資料分區,以支援大規模檔案管理和高並發請求。然而,在使用順序首碼(如時間戳記或按字典序排列的字串)的情況下,可能引起部分分區過載現象,即大量檔案集中在少數幾個分區中。
例如,當您的請求速率超過2000次/秒時(下載、上傳、刪除、拷貝、擷取中繼資料資訊等操作算1次操作,大量刪除N個檔案、列舉N個檔案等操作算N次操作),會帶來以下問題:
熱點分區形成:高頻率的請求集中在某些特定分區,使之變成熱點分區,導致分區的I/O能力被耗盡,或被系統自動限制請求速率。
請求速率受限:熱點分區的存在會觸發系統進行持續的分區資料再均衡,這個過程可能會延長請求處理時間。
說明分區資料再均衡基於即時系統狀態和處理能力分析,而非固定拆分規則,使用順序首碼命名的檔案也可能在重新均衡後仍處於熱點分區。
為解決以上問題,您可以將檔案key的順序首碼改為隨機性首碼,使得檔案索引(以及I/O負載)均勻地分布在多個分區。
向檔案key添加十六進位雜湊首碼
如果您使用日期與客戶ID組建檔案key,則包含順序時間戳記首碼:
sample-bucket-01/2024-07-19/customer-1/file1 sample-bucket-01/2024-07-19/customer-2/file2 sample-bucket-01/2024-07-19/customer-3/file3 ... sample-bucket-01/2024-07-20/customer-2/file4 sample-bucket-01/2024-07-20/customer-5/file5 sample-bucket-01/2024-07-20/customer-7/file6 ...
針對這種情況,您可以對客戶ID計算雜湊(即MD5),並取若干字元的雜湊首碼作為檔案key的首碼。假如取4個字元的雜湊首碼,那麼經過改造後的檔案key樣本變為:
sample-bucket-01/9b11/2024-07-19/customer-1/file1 sample-bucket-01/9fc2/2024-07-19/customer-2/file2 sample-bucket-01/d1b3/2024-07-19/customer-3/file3 ... sample-bucket-01/9fc2/2024-07-20/customer-2/file4 sample-bucket-01/f1ed/2024-07-20/customer-5/file5 sample-bucket-01/0ddc/2024-07-20/customer-7/file6 ...
加入4個字元組成的十六進位雜湊來作為首碼,則每個字元有0~9以及a~f共16種取值,4個字元共有16 4=65536種可能的字元組合。在儲存系統中,這些資料理論上會被持續劃分至最多65536個分區,以每個分區操作2000次/秒的效能瓶頸標準,再結合您業務的請求速率,可以評估雜湊桶的個數是否合適。
如果您想要列出檔案key中帶有特定日期的檔案,例如列出sample-bucket-01裡帶有2024-07-19的檔案,您只要對sample-bucket-01進行列舉(即通過多次調用ListObject介面,分批次地獲得sample-bucket-01下的所有檔案),然後合并帶有該日期的檔案即可。
反轉檔案key
如果您使用了毫秒精度的Unix時間戳記組建檔案key,同樣屬於順序首碼:
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 ...
這種情況可以考慮通過反轉時間戳記首碼來避免檔案key包含順序首碼,反轉後結果如下:
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 ...
由於檔案key中的前3位元字代表毫秒時間,會有1000種取值。而第4位元字,每1秒鐘就會改變一次。同理第5位元字每10秒鐘就會改變一次。以此類推,反轉檔案key將極大地增強首碼的隨機性,從而將負載壓力均勻地分攤在各個分區上,避免出現效能瓶頸。
使用位元組範圍提取
當下載OSS中的大檔案(大於100 MB)時,由於網路環境不穩定可能導致傳輸中斷。如果您只需要下載檔案的部分內容,而不是下載完整檔案的情況下,可以使用HTTP Range請求擷取檔案的部分內容。要求方法說明如下:
Get /ObjectName HTTP/1.1
Host:examplebucket.oss-cn-hangzhou.aliyuncs.com
Date:Fri, 19 Jul 2024 17:27:45 GMT
Authorization:SignatureValue
Range:bytes=[$ByteRange]
根據HTTP協議規範,Range要求標頭允許用戶端指定希望接收的資料片段有效區間位於0至content-length - 1
的範圍內。關於通過HTTP Range請求分段擷取OSS資源的更多樣本,請參見如何通過HTTP Range請求分段擷取OSS資源。
使用OSS傳輸加速
當您需要實現Bucket遠距離資料轉送加速(例如從中國內地向非中國內地Bucket請求加速上傳或下載檔案),上傳和下載GB、TB級大檔案時,您可以開啟傳輸加速。傳輸加速利用全球分布的雲機房,將全球各地使用者對Bucket的訪問,經過智能路由解析至就近的存取點,使用最佳化後的網路及協議,為雲端儲存的上傳、下載提供端到端的加速方案。更多資訊,請參見傳輸加速。
對頻繁訪問的內容使用緩衝
為提升OSS高頻訪問內容的訪問速度,推薦使用CDN加速訪問。CDN的工作原理是將靜態內容複寫至全球各地的邊緣節點,讓使用者可以從最近的節點快速擷取內容,從而大幅提升網站訪問速度和穩定性。
具體而言,當使用者請求OSS某個檔案時,CDN首先檢查邊緣節點是否存在該檔案。若不存在或檔案已到期,則向來源站點OSS請求內容並複製至附近邊緣節點。當來源站點OSS內容變更時,CDN自動更新邊緣節點緩衝,確保來源站點與CDN邊緣節點內容同步。
藉助以上方案,CDN可以有效減輕來源站點OSS負載,提高內容訪問速度及穩定性,特別適用於全球使用者廣泛分布的企業。更多資訊,請參見CDN加速訪問。
使用最新版本OSS SDK
OSS SDK為最佳化OSS效能的建議準則提供了內建支援。使用阿里雲最新版本OSS SDK對於效能提升的協助主要體現在以下幾個方面:
新特性的支援:新版SDK通常包含最新的功能和改進,能夠利用OSS的新特性,例如最新的API、最佳化的演算法和更高效的編碼方式,從而提高效能。
錯誤處理和重試機制:新版SDK通常包含更完善的錯誤處理和重試機制,能夠自動處理常見的錯誤,例如HTTP 503錯誤,減少因網路問題導致的失敗操作,提高成功率。
傳輸管理:新版SDK會提供更進階別的傳輸管理功能,自動擴充串連並在適當的時候使用範圍請求,實現高效的輸送量。
多線程支援:新版SDK通常支援多線程編程模型,可以平行處理多個請求,提高資料處理速度。
記憶體管理最佳化:考慮到記憶體資源的有效利用,新版SDK在記憶體管理層面進行了深度最佳化,旨在減少不必要的記憶體開銷,提升記憶體使用量效率。
相容性增強:新版SDK致力於修複歷史遺留問題,持續增強與各類第三方軟體庫及作業系統平台的相容性。
如何擷取阿里雲最新版本OSS SDK,請參見SDK簡介。
在同一地區內中結合使用OSS和ECS
為了充分利用阿里雲OSS和ECS的優勢,推薦您在同一地區內部署您的ECS執行個體和OSS儲存空間。這種部署策略能夠顯著減少資料轉送的延遲時間,提升資料讀取速度,從而增強應用的整體效能。 當您的ECS執行個體和OSS儲存空間位於同一個地區時,通過內網Endpoint進行通訊,可以免除內網流量費用。這意味著,在ECS執行個體與OSS之間傳輸大量資料時,無需額外支付高額的網路頻寬費用,降低了總體成本。 要實現這一配置,請參見ECS執行個體通過OSS內網地址訪問OSS資源。
對時延敏感的應用程式進行逾時重試
OSS針對管控類API,如GetService(ListBuckets)、PutBucket、GetBucketLifecycle等進行QPS限制。如果應用程式產生高請求速率,可能會收到HTTP 503減速響應。如果發生這類錯誤,建議您延遲幾秒後進行重試。
單個阿里雲帳號的總QPS為10,000,如果您需要更高的QPS,請聯絡支援人員。注意,在整體訪問QPS未超過上述閾值的情況下,如果請求集中在特定分區,服務端也可能會因為超過單分區的服務能力而限流並返回503;如果請求首碼合理打散(參見OSS效能與擴充性最佳實務),OSS會自動擴充分區數量來支援更高QPS的訪問,您只需要等待並重試即可。
當您發出大量不同大小的請求時(例如超過128 MB),建議您測量輸送量,並重試最慢的5%請求。當您發出較小的請求時(例如小於512 KB),時延通常在數十毫秒以內。建議您在2秒後重試GET或PUT操作。如果需要額外的重試,最好的做法是退出。例如,建議您在2秒後重試,然後等4秒後再次重試。
如果您的應用程式向OSS發出固定大小的請求,您期望每個請求的回應時間趨於一致。在這種情況下,推薦的策略是識別最慢的1%請求並重試。通常情況下,即使一次重試也能有效減少時延。
通過水平擴充和並行請求實現高輸送量
OSS是一個超大的分布式系統。為了協助您利用其規模,建議您將並行請求水平擴充到OSS服務終端節點,這種擴充方式有助於通過網路將負載分布在多個路徑上。
對於高輸送量傳輸,建議您在多個線程或多個執行個體中同時啟動多個請求串連來並行上傳和下載資料。對於某些應用程式,您可以通過在不同的線程或執行個體中同時啟動多個請求來實現並行串連。擴充策略取決於您的應用程式和您訪問的對象的結構。
當您要調整並發的請求數時,效能測量非常重要。建議從單個請求開始,測量當前的網路頻寬以及其他資源的使用方式,從而識別瓶頸資源(即使用率最高的資源),以及可能的並發請求數。例如,如果一次處理一個請求導致CPU使用率為10%,則表明最多可以支援10個並發請求。
水平擴充儲存串連
將請求分散在多個串連上是橫向擴充性能的常見設計模式。當您構建高效能應用程式時,可將OSS作為一個大的分布式系統,而不是像傳統儲存伺服器那樣作為單個網路終端節點。您可以通過向OSS發送多個並發請求來實現最佳效能。將這些請求分散到不同的串連上,可以最大限度地利用阿里雲OSS的可訪問頻寬。OSS對儲存空間的串連數沒有限制。
增加重試次數
鑒於阿里雲OSS的規模較大,如果第一次請求速度較慢,您可以嘗試發送重試請求。您可以通過OSS SDK配置逾時和重試值,並根據您應用程式的容錯要求進行調整。