はじめに
Cloud Storage(以降GCSと記載)経由で静的Webサイトとして公開してる場合に最新の状態が表示されないことがあり、それの原因について調査した。
構成
- LB → GCS、GCF
- 静的コンテンツはGCSへ
- 動的コンテンツはGCFへ
発生してしまった事象及びその原因
GCSではデフォルトで以下の機能があり、まるでCDNを介しているかのようにキャッシュする機能がある。
特に設定せずとも、このメタデータはデフォルトで利用される。
一般公開オブジェクトの Cache-Control メタデータにより、オブジェクトがブラウザと
インターネット キャッシュに保存される期間が決まります。デフォルトでは、一般公開オブジェクトの max-age 設定は
3,600 秒(1 時間)です。max-age には任意の長さの時間を設定できます。
参照
https://cloud.google.com/storage/docs/caching?hl=ja#built-in_caching_for
回避策
- 公開した場合GCSバケットのオブジェクトキャッシュのデフォルト設定が3600秒でありそれを変更する
- メタデータで「no-cache, max-age=0」を設定し、キャッシュが効かないように設定する
- メタデータで「max-age」を「15-60」に設定し、キャッシュが効くものの、オブジェクトが数秒間古い状態になることを許容する
https://cloud.google.com/storage/docs/caching?hl=ja#performance_considerations
public, max-age=3600
※上記はデフォルト値
対応
コンテンツ更新後も含めてどうしても最新情報を常に表示させたい、という場合、
オブジェクト配置に伴い自動でmax-ageを設定するFunctionsを設置する。
Functions設定
トリガー
ファイナライズ / 作成
対象バケットを選択
ソース(以下サンプル)
from google.cloud import storage
import traceback
def cachenone(event, context):
client = storage.Client()
#バケット及びファイル情報を取得
bucket_name = format(event['bucket'])
bucket_object = format(event['name'])
#バケットの存在確認
try:
#バケット情報取得
bucket = client.get_bucket(bucket_name)
print(bucket)
except:
print(traceback.format_exc())
print("イベント取得失敗")
print("status:ERROR")
raise
#blob情報取得
blob_object = bucket.blob(bucket_object)
print(blob_object)
#キャッシュ設定を無効化
try:
blob_object.cache_control = 'no-cache, max-age=0'
blob_object.patch()
except:
print(traceback.format_exc())
print("cache設定失敗")
print("status:ERROR")
raise
print("cache設定成功")
print("status:info")
参照
https://googleapis.dev/python/storage/latest/blobs.html
結果
オブジェクト新規設置、更新後、Functionsが稼働しキャッシュがかからないことを確認した
設定に伴注意事項
CloudStorageのキャッシュ自体はこれで無効化できるが、Cloud CDNを利用する場合、max-ageの値を利用します。
そのため、この機能を有効化したままの状態でキャッシュはCDNでおまかせ、という構成をイメージしている場合、
不可となりますので、注意が必要です。
https://cloud.google.com/storage/docs/caching?hl=ja
また、デフォルトとCDNを利用した場合の違いもあるので、要件や状態に応じて検討頂いたほうが良いと思います。個人的に特筆すべき事項だと思った部分記載します。
- キャッシュ可能な最大サイズがCDNだと5TiB
- キャッシュの無効化を記載したFunctionsなどを利用せずともCDN側で無効化設定が可能
- あとは料金面でCDNとCloudStorageでそれぞれメリットがある
https://cloud.google.com/storage/docs/caching?hl=ja#pricing_considerations
Cloud Storage
1 か月間に処理するキャッシュ可能なデータ量が数 GiB 未満の場合は、Cloud Storage の組み込みキャッシュを使用するほうが、全体的な費用が抑えられると考えられます。
CDN
1 か月あたり 100 GiB 以上のキャッシュ可能なデータを常時配信している場合、またはリクエストごとにロギングとカスタム ヘッダーを使用する必要がある場合は、Cloud CDN を使用するほうが料金を抑えられると考えられます。