使用OSS儲存卷時,如遇讀寫效能(如時延、吞吐)未達到預期的情況,可參考本文提供的排查思路和最佳化實踐,系統性地定位並解決效能問題。
OSS儲存卷更適用於順序讀寫、高頻寬需求等情境。對於需要高並發隨機寫、強依賴檔案擴充屬性(如檔案系統的owner, mode等屬性)的情境,建議評估使用NAS、CPFS等儲存卷類型,詳情請參見支援的儲存卷概覽。
用戶端實現原理
Object Storage Service的扁平化結構與檔案系統的樹形結構存在本質差異。為了讓容器內的應用能通過標準檔案系統介面(POSIX協議,如read、write、stat)訪問OSS,CSI外掛程式會在業務節點上運行一個用戶端(支援ossfs 1.0、ossfs 2.0、strmvol)。該用戶端如同一個“雙向翻譯器”,將應用對檔案的操作(如write)轉換為對OSS對象的HTTP請求(如PUT Object),並將OSS的返回結果轉換為檔案系統響應,從而“類比”出一個檔案系統。
這個轉換過程涉及網路傳輸和協議開銷,因此OSS儲存卷的效能表現與用戶端類型、網路狀況、節點資源以及業務資料訪問模式緊密相關。
排查思路指引
排查效能問題時,推薦遵循以下流程:
本文針對通過CSI以POSIX介面訪問OSS的效能排查情境。如業務代碼中直接使用了OSS SDK,其效能最佳化思路請參見OSS效能最佳實務。
確認用戶端符合預期:確認用戶端選型以及對應的效能基準(Benchmark)符合業務情境。
排查配置異常或外部瓶頸:通常與商務邏輯無關,屬於基礎配置和環境的“健全狀態檢查”,可由營運人員完成。
深入最佳化用戶端讀寫參數:如果基礎環境正常,效能問題可能與資料訪問模式和用戶端參數配置有關。建議從以下兩個層面進行最佳化:
按情境最佳化:ACK針對典型的高效能情境(如大模型部署)提供了最佳實務,詳見使用ossfs 2.0儲存卷加速大模型服務部署。
通用參數調優:如需進行更深度的自訂調優,則需深入理解業務的資料訪問模式,建議由開發人員調整代碼或配置。詳見下文的最佳化業務讀寫邏輯與用戶端參數。
開始排查前,請確保叢集CSI組件版本需為v1.33.1及以上。如需升級,請參見管理CSI組件。
確認用戶端符合預期
用戶端選型
相較於ossfs 1.0,ossfs 2.0和strmvol儲存卷在順序讀寫和高並發小檔案讀取方面均有顯著的效能提升。若業務不涉及隨機寫,可優先選擇ossfs 2.0。
若不確認業務是否有隨機寫入,可以在測試環境嘗試掛載ossfs 2.0儲存卷。若業務執行隨機寫操作,會返回EINVAL類型錯誤。
為實現效能最大化,使用ossfs 2.0用戶端時,chmod和chown操作不報錯但不生效。如需為掛載點下的檔案或目錄設定許可權,可通過PV的otherOpts欄位添加掛載參數來實現:chmod可使用-o file_mode=<許可權碼>或-o dir_mode=<許可權碼>;chown可使用-o gid=或-o uid=。
詳細的選型建議,請參見用戶端選型參考。
效能預期
OSS儲存卷作為網路檔案系統,其效能受網路和協議層影響。效能問題通常指與提供的Benchmark結果存在較大偏離,而非與本地檔案系統的效能差異。不同用戶端的基準效能參考如下。
排查配置異常或外部瓶頸
在PV上配置了公網端點
當叢集與OSS Bucket處於同一地區時,使用內網端點可大幅降低網路延遲。
排查方法:執行以下命令,檢查PV配置的OSS端點。
kubectl get pv <pv-name> -o jsonpath='{.spec.csi.volumeAttributes.url}'解決方案:如輸出為公網端點(如
http://oss-<region-id>.aliyuncs.com),請重建PV,改用內網端點(如http://oss-<region-id>-internal.aliyuncs.com)。
OSS服務端限流
OSS對單個Bucket有總頻寬和QPS(每秒請求數)的使用限制。對於部分地區的業務,及工作流程等大並發訪問OSS情境,可能出現頻寬和QPS限流。
排查方法:在OSS管理主控台查看OSS Bucket的監控指標資料,確認使用頻寬、請求次數等指標是否已接近或超過限制。
解決方案:
更換地區:OSS支援的單Bucket頻寬和QPS限制與地區相關,如果業務仍處於測試階段,可評估更換至其他地區。
頻寬出現瓶頸:
若資料沒有重複讀需求:為Pod動態掛載雲端硬碟用作臨時儲存,對臨時資料建議使用彈性臨時盤(EED)。具體操作請參見使用雲端硬碟動態儲存裝置卷,不同雲端硬碟類型效能指標請參見Block Storage效能。
若資料會在副本間或業務批次間重複讀取:使用分布式緩衝(如Fluid結合JindoFS),將OSS的資料提前預取至叢集的緩衝系統中,避免後續重複向OSS請求資料。具體操作,請參見JindoFS加速OSS檔案訪問。
QPS(或IOPS)出現瓶頸: 對於大部分業務,在並發較大時頻寬會比QPS更早觸發限流。若僅觸發QPS瓶頸,可能是由於頻繁的元資訊擷取(如
ls、stat)或頻繁的檔案開啟和關閉,需排查用戶端的配置與業務的讀寫方式。請參見下文的最佳化業務讀寫邏輯與用戶端參數進行最佳化。
業務所在節點內網頻寬到達瓶頸
用戶端與業務Pod運行在同一節點上,共用該節點的網路資源(Serverless算力情境下則共用一個ACS執行個體資源)因此,節點的網路頻寬上限會約束OSS儲存卷的效能上限。
排查方法: 查看節點監控資訊或ECS執行個體監控資訊,確認是否出現頻寬瓶頸。
解決方案:
ossfs 1.0儲存卷落盤受雲端硬碟最大吞吐限制
ossfs 1.0用戶端為了支援完整的POSIX寫操作並保證單用戶端的資料一致性,在訪問檔案時會預設將部分資料落盤。此落盤操作預設發生在ossfs Pod的/tmp下,該空間實際對應節點上用於存放容器運行時資料的雲端硬碟。因此,ossfs 1.0的效能會直接受限於這塊雲端硬碟的IOPS和輸送量上限。
排查方法:
以下方式不適用於ContainerOS節點。
執行以下指令,確認業務Pod運行所在節點的容器運行時資料盤ID。
kubectl get node <node-name> -o yaml | grep alibabacloud.com/data-disk-serial-id根據輸出中的
data-disk-serial-id,臨時空間實際位於雲端硬碟執行個體d-uf69tilfftjoa3qb****上。alibabacloud.com/data-disk-serial-id: uf69tilfftjoa3qb****若輸出中ID為空白,可訪問ECS控制台-Block Storage-雲端硬碟,根據掛載執行個體定位雲端硬碟並查詢其監控資訊。
根據擷取到的執行個體ID,查看雲端硬碟的IOPS、輸送量以及延遲指標,判斷該磁碟是否出現IOPS或吞吐瓶頸。
解決方案:
存放ossfs 1.0儲存卷臨時資料的盤水位過高
若雲端硬碟監控顯示ossfs 1.0的落盤雲端硬碟使用率始終處於高水位(尤其是Serverless算力情境下),臨時資料的頻繁淘汰和輪轉也會導致訪問效能的進一步下降。
排查方法:
參見此前的ossfs 1.0儲存卷落盤受雲端硬碟最大吞吐限制中的解決方案,確認容器運行時資料所在的雲端硬碟。
通過雲端硬碟監控查詢該盤的資源使用方式。如果使用率一直維持在穩定的高水位,而業務本身對該盤的寫入量較少,則可能是ossfs 1.0用戶端的臨時資料輪轉導致的效能問題。
解決方案:
檢查商務邏輯:確認業務代碼中是否存在長期佔用檔案描述符(即開啟檔案後長期不關閉)的行為。在檔案描述符被持有期間,其相關的臨時資料無法被釋放,會異常佔用大量本地碟空間。
擴容本地碟:如果商務邏輯無問題,且當前雲端硬碟的最大輸送量已滿足要求,則需評估擴容雲端硬碟容量。
鑒權TTL過短導致大量RAM請求
ossfs用戶端(1.0和2.0)在使用RAM角色鑒權時,會在初次訪問OSS時擷取Token並記錄其到期時間。為了保證會話的連續性,用戶端會在Token到期時間的20分鐘前,提前擷取新的Token並重新整理到期時間。
因此,RAM角色的最大會話時間(max_session_duration)必須超過20分鐘。
例如,若會話時間為30分鐘,用戶端將在Token使用10分鐘後(30 - 20 = 10)進行一次重新整理,不影響正常吞吐。若會話時間短於20分鐘,用戶端會認為Token“永遠”處於即將到期的狀態,從而在每次對OSS發起請求前都嘗試擷取新Token,引發大量的RAM請求,影響效能。
排查方法: 預設的用戶端日誌等級可能不會記錄頻繁的Token重新整理行為。需確認業務所使用的RAM角色配置正常。
解決方案: 參見設定RAM角色最大會話時間,查詢並修改RAM角色的最大會話時間,確保配置正常。
最佳化業務讀寫邏輯與用戶端參數
最佳化元資訊緩衝(並避免禁用)
元資訊緩衝是提升ls、stat等高頻操作效能的核心機制,可以大幅減少耗時的網路請求。錯誤禁用或配置不當會導致用戶端為保證資料一致性而頻繁請求OSS,造成效能瓶頸。
排查方法:
執行以下命令,確認PV配置的用戶端參數中是否包含了禁用緩衝的選項。kubectl get pv <pv-name> -o jsonpath='{.spec.csi.volumeAttributes.otherOpts}'解決方案:
避免禁用緩衝:若上述命令的輸出包含
max_stat_cache_size=0(ossfs 1.0) 或close_to_open=true(ossfs 2.0),且業務情境不屬於必須保證強一致性,建議重建儲存卷並刪除這些參數。最佳化緩衝配置:如果業務讀取的資料更新頻率較低,可主動增大元資訊緩衝的數量和失效時間,以進一步提升效能。
ossfs 1.0儲存卷:請參見中繼資料快取。
ossfs2.0儲存卷:請參見減少OSS請求並提升掛載點效能。
strmvol儲存卷:預設緩衝掛載點下的所有元資訊且不失效,通常無需額外配置。
避免維護對象擴充資訊(僅適用於ossfs 1.0)
檔案系統的mode、gid、uid等元資訊在OSS中屬於對象的擴充資訊,ossfs 1.0需要通過額外的HTTP請求擷取。雖然用戶端預設會緩衝這些元資訊(包括基本屬性和擴充屬性)以提升資料訪問效能,但頻繁的元資訊擷取,特別是包含擴充屬性的擷取,仍然是效能瓶頸之一。
因此,對此類情境的效能最佳化主要關注兩點:
儘可能減少擷取元資訊的次數,請參見最佳化元資訊緩衝(並避免禁用)。
避免請求開銷較大的擴充屬性,以降低單次擷取的時間成本。
解決方案:
業務不依賴檔案系統元資訊:建議配置
readdir_optimize參數關閉擴充資訊維護,其chmod、chown、stat等行為將等同於ossfs 2.0。業務僅需全域配置許可權:對於非root容器需要許可權等情境,建議配置
readdir_optimize參數,同時通過gid、uid、file_mode/dir_mode參數全域修改檔案系統的預設使用者或許可權。業務需要精細的權限原則:建議不通過檔案系統許可權進行存取控制。改為通過OSS服務端的鑒權體系實現路徑隔離,例如為不同業務建立不同的RAM使用者或角色,並使用Bucket Policy或RAM Policy限制其能訪問的子路徑。同時,仍應配置
readdir_optimize參數以最佳化效能。
最佳化檔案寫入模式
OSS對象的預設寫操作為覆蓋寫(Overwrite),用戶端在處理檔案修改時,需要遵循“先讀後寫”的模式:先從OSS將完整的對象讀取到本地,然後在檔案關閉後將整個檔案重新上傳至服務端。因此,在頻繁開啟、寫入、關閉檔案的極端情況下,業務實際上是在重複地、完整地下載和上傳資料。
解決方案:
批量寫入而非多次寫入:儘可能避免無意義的多次寫入。一次性將內容在記憶體中準備好,然後調用一次寫操作完成。需要特別注意,一些封裝好的寫函數(例如Java的
FileUtils.write),其內部已經包含了open、write、close的完整流程,在迴圈中反覆調用此類函數會造成效能問題。使用臨時檔案實現頻繁修改:若某個檔案在一次資料處理任務中確實需要被多次開啟和修改,建議先將它從OSS掛載點拷貝到容器內的臨時路徑(如
/tmp),在本地臨時檔案上完成所有修改操作,最後再將最終版本一次性拷貝至OSS掛載點以實現上傳。針對追加寫情境啟用Appendable特性:若業務情境僅為頻繁、小量的資料追加寫(例如日誌寫入),可評估使用ossfs 2.0,並開啟
enable_appendable_object=true參數配置。開啟後,用戶端將使用OSS的Appendable類型對象,追加資料時無需每次都下載並完整上傳整個檔案。但需注意:如果目標檔案已經存在但不是Appendable類型對象,不支援使用該方案對其進行追加寫。
enable_appendable_object是針對整個儲存卷的全域參數。開啟後,該儲存卷上所有的寫操作都會通過AppendObject介面實現,影響大檔案覆蓋寫的效能(不影響讀)。建議為該類追加寫業務建立專用的儲存卷。
最佳化並發讀模式(尤其適用於模型載入情境)
當多個進程並發地從單個大檔案內部的不同位置讀取資料時,其訪問模式接近隨機讀,容易引發用戶端冗餘地讀取資料,造成異常的多倍頻寬佔用。例如,AI模型載入情境下,主流模型架構通常由多個並發進程同時讀取同一個模型參數檔案,從而觸發效能瓶頸。
如果使用ossfs 2.0時,發現類似情境下的效能差於ossfs 1.0,或其表現與ossfs 2.0用戶端壓測效能有顯著差異,則可確認為此問題。
解決方案:
資料預熱(推薦):在業務Pod啟動前,通過指令碼實現資料預熱。其核心原理是,通過高頻寬的並發順序讀,提前將模型檔案完整地載入並緩衝至節點的記憶體(Page Cache)中。預熱完成後,業務進程的“隨機讀”將直接從記憶體中命中,從而繞過效能瓶頸。
說明為避免 Page Cache 因記憶體壓力被過早回收,建議將業務容器的記憶體限制(Memory Limit)設定為略大於模型總大小。
可參考以下可獨立啟動並執行預熱指令碼,並發地將檔案內容讀取到
/dev/null:#!/bin/bash # 設定最大並發數 MAX_JOBS=4 # 檢查是否提供了目錄作為參數 if [ -z "$1" ]; then echo "用法: $0 <目錄路徑>" exit 1 fi DIR="$1" # 檢查目錄是否存在 if [ ! -d "$DIR" ]; then echo "錯誤:'$DIR' 不是一個有效目錄。" exit 1 fi # 使用 find 找出所有普通檔案,並通過 xargs 並發執行 cat 到 /dev/null find "$DIR" -type f -print0 | xargs -0 -I {} -P "$MAX_JOBS" sh -c 'cat "{}" > /dev/null' echo "已完成所有檔案的讀取。"可將此指令碼的核心邏輯簡化,在Pod的
lifecycle.postStart中執行。# ... spec: containers: - image: your-image env: # 定義模型檔案所在的目錄路徑。若未配置或目錄不存在,指令碼將跳過資料預熱 - name: MODEL_DIR value: /where/is/your/model/ # 定義預熱指令碼的並發數,預設為 4 - name: PRELOADER_CONC value: "8" lifecycle: postStart: exec: command: ["/bin/sh", "-c", "CONC=${PRELOADER_CONC:-4}; if [ -d \"$MODEL_DIR\" ]; then find \"$MODEL_DIR\" -type f -print0 | xargs -0 -I {} -P \"$CONC\" sh -c 'cat \"{}\" > /dev/null'; fi"] # ...改造商務邏輯:評估並改造商務邏輯,將“檔案內的多進程並發讀”切換為“對多個不同檔案的並發讀”,以發揮OSS高吞吐的優勢。如在模型載入情境,部分社區已支援關閉mmap能力,以緩解多卡推理情境下的並發讀問題。
生產環境使用建議
用戶端選擇:除非業務有無法修改的隨機寫需求,優先使用ossfs 2.0儲存卷。
監控先行:日常監控OSS Bucket的頻寬和QPS、節點網路頻寬、本地碟I/O(ossfs 1.0),以便在效能問題發生時快速定位。
避免禁用緩衝:除非業務要求強一致性,否則任何情況下都不要禁用中繼資料快取。
資料預熱:對於AI推理等涉及大量資料讀取的情境,若啟動時延要求高,可評估使用資料預熱方案,但需注意這會預占節點資源和頻寬。
成本考量:OSS儲存卷功能及相關組件本身不收費,但會產生底層的OSS資源使用費(如儲存容量、API請求、資料流出流量等)。本文提到的不合理配置(如禁用緩衝、使用公網端點)和業務訪問模式,可能導致API請求量和流量激增,增加OSS使用成本。
常見問題
為什麼OSS儲存卷比節點本地碟慢很多?
這是正常的。OSS儲存卷是網路檔案系統,所有操作都需經過網路和協議轉換,其時延和吞吐與直連的本機存放區存在差異。效能評估應參考對應Benchmark。
為什麼我的業務讀取效能尚可,但寫入效能極差?
這通常與OSS對象“僅支援覆蓋上傳”的特性有關。用戶端處理檔案修改時,需先下載、再修改、最後完整上傳,此過程開銷很大。請參見最佳化檔案寫入模式進行最佳化。
如何判斷我的應用程式是否在執行隨機寫?
可在測試環境中將該應用掛載的儲存卷類型從ossfs 1.0切換為ossfs 2.0。如果應用在運行中出現檔案寫入相關的EINVAL(Invalid argument)錯誤,即可判斷其存在ossfs 2.0不支援的隨機寫操作。