調整 Cloud Storage FUSE 的重要功能和設定,有助於大幅提高處理量和效能,特別是訓練、提供和檢查點等人工智慧和機器學習 (AI/機器學習) 工作負載。本文件說明調整 Cloud Storage FUSE 效能的最佳做法。
注意事項
套用本頁建議的設定前,請考量下列事項:
您可以使用下列方法,在這個頁面套用建議設定:
Cloud Storage FUSE
profile欄位或--profile選項:使用時,會自動設定 AI/機器學習訓練、檢查點或服務工作負載。僅適用於 Google Kubernetes Engine:Google Kubernetes Engine YAML 檔案範例
請確認您使用的是最新版本 Cloud Storage FUSE。建議設定僅適用於 Cloud Storage FUSE 3.0 以上版本,以及在 GKE 叢集 1.32.2-gke.1297001 以上版本執行的 Google Kubernetes Engine 專用 Cloud Storage FUSE CSI 驅動程式。
建議設定會在工作期間快取 Cloud Storage 中繼資料,且在檔案系統初始掛接後不會檢查。因此,建議您將檔案系統設為唯讀,或將檔案系統語意設為「寫入新檔案」應用程式,也就是應用程式一律寫入新檔案,以達到最佳效能。下列 AI/機器學習工作負載會寫入新資料:
查核點機制
訓練
供應
jax.jit()快取
本頁面的建議設定已通過 Cloud GPU 和 Cloud TPU 大型機型的驗證,適用於記憶體容量大且網路介面頻寬高的環境。Cloud GPU 和 Cloud TPU 機器的可用資源數量 (例如主機節點設定中的 CPU、記憶體和本機儲存空間) 可能有所不同。這可能會直接影響下列設定的效能:
A3 Mega:1.8 TiB 記憶體,搭配 6 TiB LSSD
Cloud TPU v5e:188 GiB 記憶體,無 LSSD
Cloud TPU v5p:448 GiB 記憶體,無 LSSD
Cloud TPU v6e (Trillium):1.5 TiB 記憶體,無 LSSD
Cloud TPU 7x (Ironwood):1.1 TiB 記憶體,無 LSSD
Rapid Bucket 支援
從 3.7.1 版開始,Cloud Storage FUSE 支援採用最佳化讀取路徑的 Rapid Bucket。
最佳化讀取路徑預設會使用 Linux 核心的預讀演算法,大幅提升效能。如要使用這個最佳化讀取路徑,必須針對 read_ahead_kb、max_background 和 congestion_threshold 參數進行特定的機器層級設定變更。在採用 Cloud Storage FUSE CSI 驅動程式的 Google Kubernetes Engine (GKE) 環境中,系統會自動套用並全代管這些設定。如果是 Compute Engine VM 和其他非 GKE 環境,Cloud Storage FUSE 需要 sudo 權限才能自動套用這些變更,否則您必須手動設定這些參數。
使用 Rapid Bucket 的最佳化讀取路徑時,請注意下列行為和限制:
- 檔案快取和緩衝讀取器相容性:最佳化讀取路徑仰賴核心的預讀演算法,因此與 Cloud Storage FUSE 檔案快取和緩衝讀取器不相容。根據預設,這些功能在快速值區中為停用狀態 (無作業)。如果工作負載需要檔案快取或緩衝讀取器,您必須在掛接期間設定
enable-kernel-reader: false,明確停用核心讀取器。這會導致 Cloud Storage FUSE 使用標準讀取路徑,與檔案快取和緩衝讀取相容。 - 掛接需求:新的讀取路徑僅支援靜態掛接。使用動態掛接時不支援這項功能。
使用已啟用階層命名空間的 bucket
一律使用已啟用階層命名空間的 bucket。階層命名空間會將資料整理成階層式檔案系統結構,提高 bucket 內作業的效率,進而縮短回應時間,並減少每項作業的整體清單呼叫次數。
階層式命名空間的優點包括:
相較於平面 bucket,採用階層命名空間的 bucket 每秒查詢次數 (QPS) 最多可提高八倍。階層式命名空間每秒支援 40,000 個初始物件讀取要求,以及 8,000 個初始物件寫入要求,遠高於一般 Cloud Storage FUSE 扁平 bucket,後者每秒僅提供 5,000 個物件讀取要求,以及 1,000 個初始物件寫入要求。
階層命名空間會以不可分割的方式重新命名目錄,這是使用 Cloud Storage FUSE 設定查核點的必要條件,可確保不可分割性。大規模設定查核點時,使用啟用階層命名空間的 bucket 特別有利,因為機器學習架構會使用目錄重新命名來完成查核點,這是一項快速、不可分割的指令,且僅支援啟用階層命名空間的 bucket。如果選擇不使用已啟用階層命名空間的 bucket,請參閱「提高非 HNS bucket 的重新命名限制」。
如要瞭解如何建立已啟用階層命名空間的 bucket,請參閱「建立已啟用階層命名空間的 bucket」。如要瞭解如何掛接已啟用階層命名空間的 bucket,請參閱「掛接已啟用階層命名空間的 bucket」。Google Kubernetes Engine 1.31.1-gke.2008000 以上版本支援階層式命名空間。
執行目錄專屬掛接
如要存取 bucket 中的特定目錄,可以使用 only-dir 掛接選項,只掛接該目錄,而非整個 bucket。執行目錄專屬掛接作業時,系統會限制解析檔案名稱時要周遊的目錄數量,因此可加快清單呼叫速度,並減少清單和統計資料呼叫的總數,因為 LookUpInode 呼叫和 bucket 或目錄存取要求會自動為路徑中的每個檔案或目錄產生清單和統計資料呼叫。
如要掛接特定目錄,請使用下列其中一種方法:
Google Kubernetes Engine
如為永久磁碟區,請搭配使用下列掛接設定與 Google Kubernetes Engine 的 Cloud Storage FUSE CSI 驅動程式:
mountOptions:
- only-dir:DIRECTORY_NAME
如果是臨時磁碟區,請將掛接設定附加至 volumeAttributes.mountOptions,並以半形逗號分隔旗標:
mountOptions: "OTHER_OPTIONS,only-dir:DIRECTORY_NAME"
將 DIRECTORY_NAME 替換為要掛接的目錄名稱。
Compute Engine
執行 gcsfuse --only-dir 指令,在 Compute Engine 虛擬機器上掛接特定目錄:
gcsfuse --only-dir DIRECTORY_NAME BUCKET_NAME MOUNT_POINT
更改下列內容:
BUCKET_NAME是要掛接目錄的 bucket 名稱。DIRECTORY_NAME是要掛接的目錄名稱。MOUNT_POINT是要掛接 bucket 的本機目錄。例如:/path/to/mount/point。
如要進一步瞭解如何執行目錄掛接,請參閱「掛接 bucket 中的目錄」。
提高中繼資料快取值
如要提升重複讀取的效能,您可以設定 Cloud Storage FUSE 快取大量中繼資料,並略過中繼資料到期時間,避免重複向 Cloud Storage 發出中繼資料要求,大幅提升效能。
提高中繼資料快取值,有助於處理重複讀取的工作負載,避免重複呼叫 Cloud Storage,以及可設定無限存留時間的唯讀磁碟區。
提高中繼資料快取值前,請先考量下列事項:
只有唯讀或僅限寫入新資料的磁碟區,才能設定無限存留時間 (TTL)。
中繼資料快取會快取每個節點中指定掛接點的所有中繼資料,因此不需要額外存取 Cloud Storage。只有在記憶體設定較大的節點上,才應啟用中繼資料快取,使其大小大幅增加。
本節中的設定會以無限存留時間快取所有存取的中繼資料,如果任何其他用戶端對同一個 Cloud Storage bucket 進行變更 (例如覆寫或刪除檔案),可能會影響一致性保證。
為確保記憶體消耗量不受影響,請確認中繼資料快取消耗的記憶體量在可接受範圍內。這項數值可能會增加至數 GB,具體取決於掛接 bucket 中的檔案數量,以及使用的掛接點數量。舉例來說,每個檔案的中繼資料會占用約 1.5 KiB 的記憶體,而 100 萬個檔案的中繼資料則會占用約 1.5 GiB 的記憶體。詳情請參閱「快取總覽」。
請按照下列操作說明,設定 Cloud Storage FUSE 快取大量中繼資料,並略過中繼資料到期:
「gcsfuse」選項
gcsfuse --metadata-cache-ttl-secs=-1 \
--stat-cache-max-size-mb=-1 \
BUCKET_NAME MOUNT_POINT
更改下列內容:
BUCKET_NAME是 bucket 名稱。MOUNT_POINT是要掛接 bucket 的本機目錄。例如:/path/to/mount/point。
設定檔
metadata-cache: stat-cache-max-size-mb: -1 ttl-secs: -1
Google Kubernetes Engine
mountOptions:
- metadata-cache:ttl-secs:-1
- metadata-cache:stat-cache-max-size-mb:-1
Compute Engine
gcsfuse --metadata-cache-ttl-secs=-1 \
--stat-cache-max-size-mb=-1 \
BUCKET_NAME MOUNT_POINT
更改下列內容:
BUCKET_NAME是 bucket 名稱。MOUNT_POINT是要掛接 bucket 的本機目錄。例如:/path/to/mount/point。
預先填入中繼資料快取
建議您在執行工作負載前預先填入中繼資料快取,這樣可以大幅提升效能,並減少對 Cloud Storage 的中繼資料呼叫次數,特別是使用 implicit-dirs 欄位或 --implicit-dirs 選項時。GKE 適用的 Cloud Storage FUSE CSI 驅動程式提供 API,可處理預先填入中繼資料快取,請參閱「使用中繼資料預先擷取功能預先填入中繼資料快取」。
如要預先填入中繼資料快取,請使用下列其中一種方法:
Google Kubernetes Engine
將 gcsfuseMetadataPrefetchOnMount CSI 磁碟區屬性旗標設為 true:
在 Google Kubernetes Engine 1.32.1-gke.1357001 以上版本中,您可以使用 PersistentVolume 定義的 volumeAttributes 欄位中的 gcsfuseMetadataPrefetchOnMount 設定選項,為特定磁碟區啟用中繼資料預先擷取功能。使用 gcsfuseMetadataPrefetchOnMount 設定選項時,不需要 initContainer 方法。
apiVersion: v1
kind: PersistentVolume
metadata:
name: training-bucket-pv
spec:
...
csi:
volumeHandle: BUCKET_NAME
volumeAttributes:
...
gcsfuseMetadataPrefetchOnMount: "true"
更改下列內容:
BUCKET_NAME是 bucket 名稱。
Init 容器資源可能會因 bucket 內容和階層式版面配置而異,因此建議設定自訂中繼資料預先擷取 sidecar 資源,以提高限制。
Linux
在 Cloud Storage FUSE 掛接點上手動執行 ls -R 指令,以遞迴方式列出所有檔案,並預先填入中繼資料快取:
ls -R MOUNT_POINT > /dev/null
更改下列內容:
MOUNT_POINT:Cloud Storage FUSE 掛接點的路徑。
Compute Engine
在 Cloud Storage FUSE 掛接點上手動執行 ls -R 指令,以遞迴方式列出所有檔案,並預先填入中繼資料快取:
ls -R MOUNT_POINT > /dev/null
更改下列內容:
MOUNT_POINT:Cloud Storage FUSE 掛接點的路徑。
啟用檔案快取和並行下載
檔案快取功能可讓您將經常存取的檔案資料儲存在本機,加快重複讀取的速度,並降低 Cloud Storage 費用。啟用檔案快取時,系統也會自動啟用平行下載功能。平行下載功能會使用多個 worker,並以檔案快取目錄做為預先擷取緩衝區,平行下載檔案,因此模型載入時間可縮短九倍。
如要瞭解如何啟用及設定檔案快取和並行下載,請參閱「啟用及設定檔案快取行為」。如要使用設定範例,請參閱「啟用檔案快取和平行下載的設定範例」。
使用檔案快取和平行下載時,Cloud GPU 和 Cloud TPU 的注意事項
檔案快取可託管於本機 SSD、RAM、Persistent Disk 或 Google Cloud Hyperdisk,請參閱下列指南。在所有情況下,資料或個別大型檔案都必須符合檔案快取目錄的可用容量,該容量由 max-size-mb 欄位或 --file-cache-max-size-mb 選項控制。
Cloud GPU 注意事項
本機 SSD 相當適合用於訓練資料和查核點下載。Cloud GPU 機型包含可用的 SSD 容量,例如 A4 機型包含 12 TiB 的 SSD。
RAM 磁碟的大小比系統未使用的 RAM 量小,因此載入模型權重時效能最佳。
Persistent Disk 或 Google Cloud Hyperdisk 都能做為快取。
Cloud TPU 注意事項
Cloud TPU 不支援本機 SSD。如果您在 Cloud TPU 上使用檔案快取,但未進行修改,系統會使用預設位置 (即開機磁碟區),但我們不建議這麼做,因為這會導致效能不佳。
建議您使用 RAM 磁碟,而非開機磁碟區,因為 RAM 磁碟效能較佳,且不會產生額外費用。不過,RAM 磁碟的大小通常有限,最適合用於提供模型權重或查核點下載,具體取決於查核點大小和可用 RAM。此外,建議您使用永久磁碟和 Google Cloud Hyperdisk 進行快取。
啟用檔案快取和平行下載功能的設定範例
根據預設,如果 Google Kubernetes Engine 節點啟用 ephemeral-storage-local-ssd 模式,檔案快取會使用本機 SSD。如果沒有可用的本機 SSD (例如 Cloud TPU 機器),檔案快取會使用 Google Kubernetes Engine 節點的開機磁碟,但我們不建議這麼做。在這種情況下,您可以使用 RAM 磁碟做為快取目錄,但請考量可用於檔案快取的 RAM 數量,以及 Pod 所需的 RAM 數量。
「gcsfuse」選項
gcsfuse --file-cache-max-size-mb=-1 \
--file-cache-cache-file-for-range-read=true \
--file-cache-enable-parallel-downloads=true \
BUCKET_NAME
更改下列內容:
BUCKET_NAME是 bucket 名稱。
設定檔
file-cache: max-size-mb: -1 cache-file-for-range-read: true enable-parallel-downloads: true
Cloud GPU
mountOptions:
- file-cache:max-size-mb:-1
- file-cache:cache-file-for-range-read:true
- file-cache:enable-parallel-downloads:true
# RAM disk file cache if LSSD not available. Uncomment to use
# volumes:
# - name: gke-gcsfuse-cache
# emptyDir:
# medium: Memory
Cloud TPU
mountOptions:
- file-cache:max-size-mb:-1
- file-cache:cache-file-for-range-read:true
- file-cache:enable-parallel-downloads:true
volumes:
- name: gke-gcsfuse-cache
emptyDir:
medium: Memory
Compute Engine
gcsfuse --file-cache-max-size-mb=-1 \
--file-cache-cache-file-for-range-read=true \
--file-cache-enable-parallel-downloads=true \
BUCKET_NAME MOUNT_POINT
更改下列內容:
BUCKET_NAME是 bucket 名稱。MOUNT_POINT是要掛接 bucket 的本機目錄。例如:/path/to/mount/point。
停用負面統計資料快取項目
根據預設,Cloud Storage FUSE 會快取負值統計資料項目 (即不存在的檔案項目),存留時間為五秒。在經常建立或刪除檔案的工作負載中 (例如分散式檢查點),這些快取項目可能會很快過時,導致效能問題。為避免這種情況,建議您使用 negative-ttl-secs 欄位或 --metadata-cache-negative-ttl-secs 選項,停用訓練、服務和檢查點工作負載的負狀態快取。
請按照下列操作說明停用負面統計資料快取:
gcsfuse選項
gcsfuse --metadata-cache-negative-ttl-secs=0 \ BUCKET_NAME
更改下列內容:
BUCKET_NAME是 bucket 名稱。
設定檔
metadata-cache: negative-ttl-secs: 0
Google Kubernetes Engine
mountOptions:
- metadata-cache:negative-ttl-secs:0
Compute Engine
gcsfuse --metadata-cache-negative-ttl-secs=0 \ BUCKET_NAME MOUNT_POINT
更改下列內容:
BUCKET_NAME是 bucket 名稱。MOUNT_POINT是要掛接 bucket 的本機目錄。例如:/path/to/mount/point。
啟用串流寫入
串流寫入作業會在寫入資料時,直接將資料上傳至 Cloud Storage,進而減少延遲時間和磁碟空間用量。這對檢查點等大型循序寫入作業特別有利。Cloud Storage FUSE 3.0 以上版本預設會啟用串流寫入功能。
如果預設未啟用串流寫入,請按照下列操作說明啟用。如要啟用串流寫入功能,必須使用 Cloud Storage FUSE 3.0 版,該版本適用於 Google Kubernetes Engine 1.32.1-gke.1729000 以上版本。
gcsfuse選項
gcsfuse --enable-streaming-writes=true \ BUCKET_NAME
更改下列內容:
BUCKET_NAME是 bucket 名稱。
設定檔
write: enable-streaming-writes: true
Google Kubernetes Engine
mountOptions:
- write:enable-streaming-writes:true
Compute Engine
gcsfuse --enable-streaming-writes=true \ BUCKET_NAME MOUNT_POINT
更改下列內容:
BUCKET_NAME是 bucket 名稱。MOUNT_POINT是要掛接 bucket 的本機目錄。例如:/path/to/mount/point。
啟用緩衝讀取
緩衝讀取功能會以非同步方式,將 Cloud Storage 物件的部分內容預先擷取至記憶體內緩衝區,可將大型檔案的依序讀取效能提升兩到五倍。這樣一來,後續的讀取作業就能從緩衝區提供,不必發出網路呼叫。
啟用緩衝讀取前,請考量下列事項:
緩衝讀取與檔案快取不相容。如果同時啟用緩衝讀取和檔案快取,系統會優先採用檔案快取,並忽略緩衝讀取。
緩衝讀取作業可能會占用大量記憶體和運算資源。
如要啟用緩衝讀取功能,請按照下列操作說明進行:
CLI 選項
gcsfuse --enable-buffered-read=true \ BUCKET_NAME
更改下列內容:
BUCKET_NAME是 bucket 名稱。
設定檔
read: enable-buffered-read: true
增加核心預讀大小
如果工作負載主要涉及大型檔案的依序讀取作業 (例如提供模型和從查核點還原模型),增加預讀大小可大幅提升效能。您可以在本機電腦上使用 read_ahead_kb Linux 核心參數來完成這項操作。建議您將 read_ahead_kb 核心參數增加至 1 MB,而非使用大多數 Linux 發行版設定的預設值 128 KB。如果是 Compute Engine 執行個體,則必須具備 sudo 或 root 權限,才能成功提高核心參數。
如要將特定 Cloud Storage FUSE 掛接目錄的 read_ahead_kb 核心參數提高至 1 MB,請按照下列操作說明操作。執行指令前,必須先將 bucket 掛接至 Cloud Storage FUSE,否則核心參數不會增加。
如果是可用區 bucket,Cloud Storage FUSE 會在 Google Kubernetes Engine 1.35.0-gke.3047001 以上版本,以及使用 Cloud Storage FUSE 3.7.0 以上版本的 Compute Engine 環境中,自動管理 read_ahead_kb 核心參數。由於這項作業會自動處理,因此 read_ahead_kb 掛接選項不再適用,系統會忽略您提供的任何值。請注意,在 Compute Engine 環境中,Cloud Storage FUSE 需要 root 或無密碼 sudo 權限,才能自動管理這項參數。
Google Kubernetes Engine
mountOptions: - read_ahead_kb=1024
Compute Engine
export MOUNT_POINT=/path/to/mount/point echo 1024 | sudo tee /sys/class/bdi/0:$(stat -c "%d" $MOUNT_POINT)/read_ahead_kb
更改下列內容:
/path/to/mount/point:本機檔案系統中掛接 Cloud Storage bucket 的路徑。
停用 Security Token Service,避免重複檢查
Google Kubernetes Engine 的 Cloud Storage FUSE CSI 驅動程式會執行存取權檢查,確保 Pod 可復原,避免使用者誤設 bucket 與 GKE 服務帳戶之間的工作負載身分繫結,導致大規模達到預設的 Security Token Service API 配額。如要停用這項功能,請設定永久磁碟區 CSI 驅動程式的 skipCSIBucketAccessCheck 磁碟區屬性。建議您確認 GKE 服務帳戶具備目標 Cloud Storage bucket 的適當存取權,以免 Pod 掛接失敗。
此外,如果 Google Kubernetes Engine 叢集包含超過 6,000 個節點,則必須將 Security Token Service 配額提高至預設值 6000 以上,否則在大規模部署中可能會導致 429 錯誤。您必須透過「配額與限制」頁面提高 Security Token Service 配額。建議您將配額設為與掛接數量相同,例如,如果叢集有 10,000 個掛接,配額應增加至 10000。
如要設定 skipCSIBucketAccessCheck 磁碟區屬性,請參閱下列範例設定:
volumeAttributes:
- skipCSIBucketAccessCheck: "true"
最佳化 OCDBT Orbax 檢查點的效能
如果工作負載使用 OCDBT 格式的 Orbax 檢查點,您可以按照下列指引,提升服務和檢查點還原效能:
將大型透明分頁設為
always:將大型透明分頁設為always,可減少記憶體片段和系統呼叫,進而提升效能。這項設定在分配大量記憶體時最有效,這在這些工作負載中很常見。Cloud TPU 機器預設會進行這項設定,其他機型則需手動設定。如要在本機電腦上啟用透明大頁,請使用root權限執行下列指令。echo always | tee /sys/kernel/mm/transparent_hugepage/enabled
在 GKE 環境中,您可以建立具特殊權限的 Pod 來執行相同操作。
增加核心預讀大小:將核心預讀大小增加至 1024 KB,可提升循序讀取效能。詳情請參閱「增加核心預讀大小」。
將
ocdbt_target_data_file_size設為 200 MiB:將ocdbt_target_data_file_size設為 200 MiB,這是 Cloud Storage FUSE 讀取效能的最佳值。使用 DNS 快取:DNS 快取會在本機快取 DNS 查詢,藉此縮短延遲時間。在 GKE 中,您可以啟用 NodeLocal DNSCache 來快取 DNS 查詢。或者,您也可以在 Compute Engine 使用 Cloud Storage FUSE 3.5 以上版本,或在 GKE 環境使用 GKE 1.34.1-gke.3899000 以上版本。
其他效能考量
除了上述主要最佳化措施,還有其他幾項因素會大幅影響 Cloud Storage FUSE 的整體效能。以下各節說明使用 Cloud Storage FUSE 時,建議考量的其他效能注意事項。
提高非 HNS bucket 的重新命名限制
設定工作負載查核點時,一律應使用已啟用階層命名空間的 bucket,因為這類 bucket 可不可分割且更快速地重新命名,且讀寫 QPS 較高。不過,如果您願意承擔目錄重新命名作業並非不可分割,且耗時較長的風險,可以使用 rename-dir-limit 欄位或 --rename-dir-limit 選項,在使用不含階層命名空間的 bucket 執行檢查點作業時,指定任何指定時間內,目錄重新命名作業涉及的檔案或作業數量上限。
建議將這項設定設為較高的值,以免查核點設定失敗。Cloud Storage FUSE 使用一般命名空間,且物件不可變更,因此重新命名目錄時,會重新命名及刪除目錄中的所有個別檔案。您可以設定 rename-dir-limit
gcsfuse 選項,控制受重新命名作業影響的檔案數量。
請按照下列操作說明設定 rename-dir-limit 設定選項:
gcsfuse選項
gcsfuse --rename-dir-limit=200000 \ BUCKET_NAME
更改下列內容:
BUCKET_NAME是 bucket 名稱。
設定檔
file-system: rename-dir-limit: 200000
Google Kubernetes Engine
mountOptions:
- rename-dir-limit=200000
Compute Engine
gcsfuse --rename-dir-limit=200000 \ BUCKET_NAME MOUNT_POINT
更改下列內容:
BUCKET_NAME是 bucket 名稱。MOUNT_POINT是要掛接 bucket 的本機目錄。例如:/path/to/mount/point。
核心清單快取
清單快取是目錄和檔案清單或 ls 回應的快取,可提高清單作業的速度。與 Cloud Storage FUSE 管理的統計資料快取不同,清單快取會保留在核心的頁面快取中,並由核心根據記憶體可用性控管。
啟用核心清單快取功能,最適合下列用途:
具有重複目錄清單的工作負載:這項設定特別適用於經常執行完整目錄清單的工作負載,例如 AI/機器學習訓練執行作業。這對提供和訓練工作負載都有幫助。
唯讀掛接:建議搭配唯讀掛接使用清單快取,避免一致性問題。
啟用核心清單快取時應謹慎,且只有在檔案系統確實為唯讀,且在工作執行期間不會變更目錄內容時,才應使用。這是因為有了這個旗標,本機應用程式就不會看到更新,尤其是 TTL 設為 -1 時。
舉例來說,「Client 1」會列出 directoryA,這會導致 directoryA 成為核心清單快取中的常駐項目。用戶端 2 在 Cloud Storage bucket 的 directoryA 下建立 fileB。用戶端 1 會持續檢查 directoryA 中的 fileB,這基本上是檢查核心清單快取項目,且絕不會透過網路進行。用戶端 1 不會看到目錄中有新檔案,因為檔案清單會持續從本機核心清單快取提供。用戶端 1 隨後逾時,程式中斷。
請按照下列指示啟用清單快取功能:
gcsfuse選項
gcsfuse --kernel-list-cache-ttl-secs=-1 \ BUCKET_NAME
更改下列內容:
BUCKET_NAME是 bucket 名稱。
設定檔
file-system: kernel-list-cache-ttl-secs: -1
Google Kubernetes Engine
mountOptions:
- file-system:kernel-list-cache-ttl-secs:-1
Compute Engine
gcsfuse --kernel-list-cache-ttl-secs=-1 \ BUCKET_NAME MOUNT_POINT
更改下列內容:
BUCKET_NAME是 bucket 名稱。MOUNT_POINT是要掛接 bucket 的本機目錄。例如:/path/to/mount/point。
使用 file-system:kernel-list-cache-ttl-secs 掛接選項時,各值的意義如下:
正值代表目錄清單回應在核心頁面快取中的存留時間 (以秒為單位)。
如果值為
-1,系統會略過項目到期時間,並在可用時從快取傳回清單回應。
搭配使用 JAX 永久編譯 (JIT) 快取和 Cloud Storage FUSE
JAX 支援即時 (JIT) 快取,這是一種選用的永久編譯快取,可儲存編譯的函式構件。使用這個快取,可以避免重複編譯步驟,大幅加快後續指令碼執行速度。
如要啟用 JIT 快取,您必須符合下列條件:
使用最新版 JAX:使用 JAX 0.5.1 以上版本,取得最新快取功能和最佳化。
盡可能提高快取容量:為避免快取淘汰導致效能降低,建議您設定不限大小的快取,尤其是要覆寫預設設定時。您可以設定環境變數來達成這個目的:
export JAX_COMPILATION_CACHE_MAX_SIZE=-1
確保檢查點 Pod YAML:使用檢查點設定,為 JAX JIT 快取設定掛接點。
為 A4X 設定接收流程導引 (RFS)
在 Compute Engine 執行個體上,接收封包導向 (RPS) 和接收流量導向 (RFS) 會搭配運作,以智慧方式將網路封包處理作業分配給多個 CPU,進而提升網路效能。如果機型 (例如 A4X) 的網路流量較高,建議採用這些設定。
RPS 會將傳入的網路封包分配給不同的 CPU 處理。這有助於平衡負載,避免單一 CPU 成為瓶頸,對於高頻率網路流量特別有用,並可降低延遲。
RFS 以 RPS 為基礎,可提高 CPU 快取效率,進一步縮短網路延遲時間。這項功能會將封包導向特定的 CPU 核心,也就是執行將使用封包的應用程式的核心,進而提高 CPU 的資料快取命中率,並降低網路延遲。
效能優勢
RFS 可大幅提升各種工作負載的效能,輸送量最多可提高 40%。
注意事項
雖然這些設定在負載下有效,但可能不適用於所有情境:
單一執行緒或單一流程工作負載:當所有網路流量都使用單一網路連線 (例如透過一個 TCP 連線傳輸單一大型檔案) 時,就會發生單一流程工作負載。這類應用程式通常不會獲得太多好處,甚至可能稍微降低處理量 (例如在特定 nginx 測試中降低約 7.7%)。高效能環境中通常很少有單一流程應用程式。
頻繁遷移執行緒:如果應用程式執行緒經常在 CPU 之間移動,RFS 會持續更新 CPU 對應(例如應用程式使用大型動態背景工作執行緒集區,要求經常在不同核心之間交接),這可能會導致過多的跨 CPU 流量和封包重新排序。
設定指令碼
在 Compute Engine 執行個體的客體作業系統上執行下列指令碼。指令碼需要 sudo 或 root 權限,才能修改核心參數。
指令碼會啟用 RPS、以輪流方式將網路佇列對應至可用的 CPU,並將每個佇列的流程表大小設為 65536。
#!/bin/bash
set -e
# Note: This script uses 'apt' and is intended for Debian-based systems.
# If 'iproute2' is not found, you may need to run 'sudo apt update' first.
sudo apt install -y iproute2
# This script enables and configures RPS (Receive Packet Steering) and RFS
# (Receive Flow Steering) for the primary network interface.
# It creates a 1:1 mapping of CPUs to receive queues and sets a specific
# flow count for each queue.
# --- Configuration ---
# The desired number of flow entries per receive queue.
RPS_FLOW_CNT_PER_QUEUE=65536
# --- Script Body ---
# 1. Auto-detect the primary network interface.
INTERFACE=$(ip route | grep default | awk '{print $5}' | head -n 1)
if [ -z "$INTERFACE" ]; then
echo "Error: Could not determine the primary network interface."
exit 1
fi
echo "Primary network interface detected: $INTERFACE"
echo "Starting RPS/RFS configuration for interface: $INTERFACE"
# 2. Determine the number of receive queues for the interface.
NUM_QUEUES=$(ls -d /sys/class/net/$INTERFACE/queues/rx-* 2>/dev/null | wc -l)
if [ "$NUM_QUEUES" -eq 0 ]; then
echo "Error: No receive queues found for interface $INTERFACE."
echo "Please check if the network driver supports multi-queue."
exit 1
fi
echo "Found $NUM_QUEUES receive queues for interface $INTERFACE."
# 3. Determine the number of CPUs.
NUM_CPUS=$(nproc)
if [ -z "$NUM_CPUS" ] || [ "$NUM_CPUS" -eq 0 ]; then
echo "Error: Could not determine the number of CPUs."
exit 1
fi
echo "Found $NUM_CPUS CPUs."
# 4. Calculate and set the total socket flow entries.
# This is the total number of entries in the global socket flow table.
RPS_SOCK_FLOW_ENTRIES=$((NUM_QUEUES * RPS_FLOW_CNT_PER_QUEUE))
echo "Setting the total RPS socket flow entries to $RPS_SOCK_FLOW_ENTRIES..."
if ! echo "$RPS_SOCK_FLOW_ENTRIES" | sudo tee /proc/sys/net/core/rps_sock_flow_entries > /dev/null; then
echo "Error: Failed to set rps_sock_flow_entries. Please run with sufficient privileges."
exit 1
fi
# 5. Configure each receive queue.
for i in $(seq 0 $((NUM_QUEUES - 1))); do
RX_QUEUE="/sys/class/net/$INTERFACE/queues/rx-$i"
# a) Assign a CPU to this queue (round-robin).
CPU_INDEX=$((i % NUM_CPUS))
CPU_BITMAP_HEX=$(printf '%x' $((1 << CPU_INDEX)))
echo "Assigning CPU $CPU_INDEX (bitmap: $CPU_BITMAP_HEX) to queue rx-$i"
if ! echo "$CPU_BITMAP_HEX" | sudo tee "$RX_QUEUE/rps_cpus" > /dev/null; then
echo "Error writing bitmap to $RX_QUEUE/rps_cpus"
exit 1
fi
# b) Set the flow count for this queue.
echo "Setting flow count for $RX_QUEUE to $RPS_FLOW_CNT_PER_QUEUE"
if ! echo "$RPS_FLOW_CNT_PER_QUEUE" | sudo tee "$RX_QUEUE/rps_flow_cnt" > /dev/null; then
echo "Error writing to $RX_QUEUE/rps_flow_cnt"
exit 1
fi
done
echo "RPS and RFS configuration updated successfully for $INTERFACE."