本頁討論如何將檔案轉成「gzip」壓縮狀態與解壓縮,內容包括轉碼概述、處理關聯中繼資料的最佳做法,以及 Cloud Storage 的壓縮檔行為。
轉碼和 gzip
gzip 是一種資料壓縮格式,一般用來減少檔案大小。這可以讓檔案的傳輸比未壓縮時快,且佔用的儲存空間較少。壓縮檔案有助減少成本和傳輸時間。Cloud Storage 的「轉碼」功能會自動變更檔案壓縮,再將檔案提供給要求者。當轉碼功能使檔案變成 gzip 壓縮時,這個檔案會被視為「壓縮」,反之,當產生的檔案不再是 gzip 壓縮狀態,就會被視為「解壓縮」。Cloud Storage 支援解壓縮格式的轉碼。
Cloud Storage 不支援 Brotli 壓縮物件的解壓縮轉碼。
解壓縮轉碼
解壓縮轉碼功能可讓您在 Cloud Storage 中儲存檔案的壓縮版本,藉此降低靜態儲存費用,同時將未經壓縮的檔案提供給要求者。對於像是提供檔案給客戶的情況,此功能非常實用。
物件必須滿足兩項條件,才能使用解壓縮轉碼:
檔案以 gzip 壓縮格式儲存於 Cloud Storage。
物件的中繼資料包括
Content-Encoding: gzip
。
當物件滿足這兩項條件,那麼就會在提供時進行解壓縮轉碼,且包含該物件的回應不會含有 Content-Encoding
或 Content-Length
標頭。
如要防止符合條件的物件發生解壓縮轉碼,有兩種方法:
如果物件的要求包括
Accept-Encoding: gzip
標頭,則針對此特定要求,物件會以原狀提供,並加上Content-Encoding: gzip
回應標頭。如果物件的
Cache-Control
中繼資料欄位設定為no-transform
,則不論任何Accept-Encoding
要求標頭為何,物件都會在所有後續要求中以壓縮物件的形式提供。
舉例來說,如果您想降低輸出資料傳輸費用或時間,或是想驗證下載的物件是否具有預期的 crc32c/md5 總和檢查碼,防止解壓縮轉碼就很有用。
注意事項
使用解壓縮轉碼時,請注意下列事項:
解壓縮轉碼會使完整性檢查失效。如果資料的要求者需要使用檢查碼進行完整性檢查,請勿使用解壓縮轉碼。
解壓縮轉碼可讓您將物件以壓縮狀態儲存在 Cloud Storage 中,節省空間和成本。不過,物件的下載費用會以「解壓縮」大小為準,因為這才是提供物件的大小。
從 Cloud Storage FUSE 掛接值區內存取物件時,物件不會經過解壓縮轉碼,而是以壓縮格式讀取。
Content-Type 和 Content-Encoding 的比較
關於 Content-Type
和 Content-Encoding
與轉碼之間的關係,有幾個行為應該注意。這兩者都是隨物件一起儲存的中繼資料,請參閱查看及編輯物件中繼資料一文,瞭解如何將中繼資料新增到物件的逐步操作說明。
Content-Type
應包含在所有上傳作業中,並指示上傳中物件的類型。例如:
Content-Type: text/plain
表示上傳的物件是純文字檔案。雖然不會執行任何檢查來確保指定的 Content-Type
符合所上傳物件的真正性質,但類型指定錯誤的話,絕對會造成要求者收到非預期中的內容,並且可能導致不希望發生的行為。
Content-Encoding
是選用項目,可視需要包含在壓縮檔案的上傳作業。例如:
Content-Encoding: gzip
表示上傳的物件為 gzip 壓縮檔。至於 Content-Type
,不會執行任何檢查來確保指定的 Content-Encoding
會確實套用至上傳的物件,且物件編碼指定錯誤的話,可能會導致後續的下載要求發生不希望發生的行為。
建議做法
上傳 gzip 壓縮物件時,建議您在設定中繼資料時,同時指定
Content-Type
和Content-Encoding
。例如,對於壓縮的純文字檔案,可指定:Content-Type: text/plain Content-Encoding: gzip
這樣可提供最多物件狀態相關資訊給存取物件的任何人,此外,也會讓物件可以在之後下載時進行解壓縮轉碼,讓用戶端應用程式正確處理
Content-Type
的語意。或者,您可以在上傳物件時設定
Content-Type
來指示壓縮,並且不使用任何Content-Encoding
。例如:Content-Type: application/gzip
不過,在這個情況下,對於這個物件,只能馬上知道它是 gzip 壓縮,對於物件類型將一無所悉。而且,物件也會無法進行解壓縮轉碼。
不建議的做法
雖然可以這樣做,但不建議上傳 gzip 壓縮檔時,將檔案的壓縮性質刪去。例如,對於 gzip 壓縮純文字檔案,應避免只設定
Content-Type: text/plain
而已,以免傳送給要求者的物件狀態遭到扭曲。同理,物件不可在省略
Content-Type
的情況下上傳,即使已包含Content-Encoding
,否則可能導致將Content-Type
設為預設值,但根據上傳的執行方式,可能會造成要求被拒。
錯誤的做法
您不應設定中繼資料,重複回報物件的壓縮。
Content-Type: application/gzip Content-Encoding: gzip
這是指重複上傳早已是 gzip 壓縮的 gzip 壓縮物件,但其實通常不該如此 (如果您「確實」需要重複壓縮檔案,請參閱以下的對壓縮物件使用 gzip 一節)。當解壓縮轉碼發生在回報錯誤的物件時,該物件會以身分編碼的狀態提供,但要求者會「認為」收到的物件仍有關聯的壓縮層。對物件解壓縮將會失敗。
同理,非 gzip 壓縮檔上傳時不應包含
Content-Encoding: gzip
。否則,物件會「看起來似乎」可以進行轉碼,但要求物件時,轉碼作業會失敗。
對壓縮物件使用 gzip
有些物件如許多影片、音訊和影像檔等,本身不會提到 gzip 檔案,但其實已經過壓縮。對這類的物件使用 gzip,幾乎毫無助益:幾乎在所有情況下,這樣做會使物件因 gzip 作業負擔而變大。因此,一般不建議對壓縮內容使用 gzip,以免可能導致不希望發生的行為。
舉例來說,Cloud Storage 允許上傳及儲存「雙重壓縮」物件 (也就是經過 gzip 壓縮,但基礎 Content-Type
本身也經過壓縮的物件),但除非物件的 Cache-Control
中繼資料包含 no-transform
,否則不允許以雙重壓縮狀態提供物件。相反的,它會移除外部 gzip 壓縮層,捨棄 Content-Encoding
回應標頭,然後提供結果物件。即使要求包含 Accept-Encoding: gzip
也不例外。因此,用戶端收到的檔案與上傳並儲存在 Cloud Storage 中的檔案,兩者總和檢查碼不同,導致任何完整性檢查都會失敗。
使用 Range 標頭
轉碼發生時,如果物件的要求包含 Range
標頭,則會在不發出通知的情況下略過該標頭。也就是說,要求提供局部內容是無法實現的,而回應會改為提供整個要求的物件。舉例來說,如果您的 10 GB 物件可以進行轉碼,但在要求中包含了 Range: bytes=0-10000
標頭,您還是會收到 10 GB 的整個物件。
這種行為的發生,是因為如果沒有先將整個壓縮檔解壓縮,就無法選取其中的範圍;為了達成對提供檔案其中一部分的要求,而將整個可能很大的檔案解壓縮,等於用不妥當的方式來利用資源。您應注意這種行為,並且避免使用 Range
標頭來進行轉碼功能,因為這會依傳送整個物件來計費,而非只用傳送要求的範圍來計費。如要進一步瞭解使用 Range
標頭發出要求所允許的回應行為,請參閱規格。
如果需要使用 Range
標頭來發出要求,請確保不會對所要求的物件進行轉碼。您可以在上傳物件時選擇適當的屬性來達成這項目標。例如,使用 Content-Type: application/gzip
但不使用 Content-Encoding
對物件提出範圍要求,將會按照這樣的要求來執行。
後續步驟
- 瞭解在使用
gcloud storage cp
時的--gzip-local
標記,這個標記會將 gzip 內容編碼套用於檔案上傳。 - 瞭解如何檢視及編輯物件中繼資料。