見出し画像

Cloud Storageの組み込みキャッシュを無効にして画像キャッシュの有効期間を設定しやすくした

こんにちは。マキシムのサービス開発部でエンジニアマネージャーをやっている井川です。

マキシムで使用している画像サーバのキャッシュ周りの設定を改善したので対応内容を紹介します。


背景

マキシムのECサイトのインフラはGoogle Cloudを使用しており、画像サーバは下記のツールを組み合わせて構築しています。

  • Google Cloud Storage(以下、GCS)

  • Load Balancing(以下、LB)

  • Cloud CDN(以下、CDN)

ただしこの構成だと下記の課題がありました。

  • 画像を上書きした時(=差し替えた時)に、反映されるまでに時間がかかる

  • キャッシュは「GCSの組み込みキャッシュ」と「CDNキャッシュ」が有効になっているため、全体的なキャッシュの有効期間がわかりづらい

特に画像の差し替え作業を行うデザイナーにとっては無駄な待ち時間が発生していたため、下記の事項の改善を目標に対応を行いました。

  • キャッシュの有効期間をわかりやすくすること

  • キャッシュ反映の待ち時間を少なくすること

対応内容

下記の対応を行いました。

  • GCSファイルの組み込みキャッシュを無効にするCloud Functionsの関数を作成

    • キャッシュはCDNの設定に基づいて配信するようにする

  • CDNのキャッシュ作成モードを FORCE_CACHE_ALL に変更

  • キャッシュの有効期間はCDNの デフォルト TTLクライアント TTL で設定する運用に変更

次にそれぞれの内容の詳細を記載します。

GCSファイルの組み込みキャッシュを無効にするCloud Functionsの関数を作成

GCSでは公式ページにも記載があるように、ファイルアップロード時にファイルに対して組み込みのキャッシュが有効になっています。
この機能のおかげでGCS単体で使用する場合にもCDNのように動作するのですが、今回の構成ではCloud CDNがあるためキャッシュの管理が2重になってしまいます。
GCSの組み込みキャッシュを無効にするには、GCS内ファイルの Cache-Control ヘッダーの内容を編集することで設定が可能です。
GCPコンソール画面から1つ1つのファイルに対して手動でメタデータ設定も可能ですが、通常の運用時に手動で設定することは現実的ではないので、GCSへのファイルアップロード時に該当のファイルの組み込みキャッシュを無効にする関数をCloud Functionsで作成しました。
Cache-Control ヘッダーには no-store, max-age=0 を指定してキャッシュを無効にしています。

const {Storage} = require('@google-cloud/storage');

functions.cloudEvent('deleteCache', cloudEvent => {
    const file = cloudEvent.data;
    const storage = new Storage();

    const bucket = file.bucket;
    const fileName = file.name;
    const cacheControl = 'no-store, max-age=0';
    try {
        const targetFile = storage.bucket(bucket).file(fileName);
        targetFile.setMetadata({
            cacheControl: cacheControl,
        });
    } catch (error) {
        console.error(error);
    }
});

CDNのキャッシュ作成モード

Cloud CDNには3つのキャッシュモードがあります。

  • CACHE_ALL_STATIC

  • USE_ORIGIN_HEADERS

  • FORCE_CACHE_ALL

画像サーバとして使用しているGCSには文字通り画像ファイル(=静的コンテンツ)しかありません。
つまり動的なHTMLなどのコンテンツは存在しないため、GCSバケット内のファイル全てをCDN上でキャッシュ化するFORCE_CACHE_ALLを設定しました。 これでキャッシュはCDNから生成されることとなります。

キャッシュの有効期間

Cloud CDNには3種類のTTL設定がありますが、FORCE_CACHE_ALLモードで使用するTTL設定は次の2つになります。

  • デフォルト TTL

    • CDNが発行するキャッシュのTTL

  • クライアント TTL

    • クライアントで保持するローカルキャッシュのTTL

この2つの値はデフォルト TTL > クライアント TTLの値となるよう設定します。そうしないとデフォルト TTLの設定が事実上無効になるからです。
各TTL設定が期限切れになった時は以下の挙動になります。

  • デフォルト TTL

    • オリジン(今回はGCS)への問い合わせを行う

  • クライアント TTL

    • CDNへの問い合わせを行う

上記の仕様になるため、デフォルト TTLが長すぎるとGCSのファイルを上書きした時に反映されるまでの時間が長くなります。このTTL設定は運用に合わせて都度調整していくのが良いかと思います。
マキシムではクライアント TTL = デフォルト TTLの半分の値となるよう設定を行っています。

まとめ

上記の対応を行うことでキャッシュの有効期間はわかりやすくなりました。
キャッシュ反映の待ち時間はデフォルト TTLの設定に左右されるのですが、サーバの利用頻度やファイルアップロード作業を行うデザイナーと相談しつつ適切な値を調整していきたいと思っています。

参考

Cloud Storage + LB + Cloud CDN で静的 Web サイトをホスティングする際のキャッシュ設定をおさらい

マキシムではワクワクドキドキできるものづくりを一緒に行う仲間を募集中です。

ご興味がございましたら、以下のURLからカジュアル面談のお申込みやご応募等お気軽にご連絡ください。