皆さん、こんにちは! 現場の最前線でパケットと格闘しているSRE兼クラウドアーキテクトの〇〇です。
今日は、皆さんのWebサイトやWebアプリケーションをサクサク動かすために欠かせない、GCPの「Cloud CDN」について、その心臓部とも言える「キャッシュキー(Cache Key)」にスポットを当てて、とことん深掘りしていきたいと思います!
「CDN? キャッシュ? キー? なんか難しそう…」と思ったそこのあなた! 大丈夫です。今回は小難しい専門用語は極力避け、郵便配達やお店のポイントカードなど、身近な例え話を交えながら、一歩ずつ丁寧に紐解いていきますからね。
Cloud CDNって、そもそも何だっけ?(おさらい)
まずはおさらいからいきましょうか。Cloud CDN(Content Delivery Network)とは、皆さんのWebサイトやアプリで配信している画像、CSS、JavaScriptなどの静的コンテンツを、ユーザーに一番近い場所から高速に届けるための仕組みです。
ちょっと想像してみてください。東京にあるWebサイトのサーバーから、北海道にいるユーザーが画像をダウンロードしようとすると、データは長い道のりを旅して北海道までやってきますよね。時間がかかりますし、途中で渋滞に巻き込まれることもあります。
そこでCDNの出番です! CDNは、世界中のあちこちに「キャッシュサーバー」と呼ばれる中継地点を置いています。北海道のユーザーがWebサイトにアクセスすると、CDNは「あら、北海道のユーザーさんね! じゃあ、一番近い札幌のキャッシュサーバーからこの画像、サッと届けちゃおう!」と、そのユーザーに一番近い場所にあるキャッシュサーバーからコンテンツを届けてくれるんです。
まるで、遠い実家から送られてくる荷物が、途中の営業所で一時的に保管されていて、すぐに地元の配達員さんが届けてくれるようなイメージですね。これにより、ユーザーは「え、もう表示されたの!?」と驚くほど快適にWebサイトを見ることができるようになります。
キャッシュキーって、何のこと?
さて、本題の「キャッシュキー」です。キャッシュキーとは一体何なのでしょう?
先ほどの郵便配達の例で考えてみましょう。札幌の営業所には、たくさんの荷物が一時的に保管されていますよね。その荷物一つ一つには、宛先の住所や荷物番号が書かれています。配達員さんは、その情報を見て「この荷物は〇〇さんの家へ」「こっちの荷物は△△さんのマンションへ」と区別して配達します。
Cloud CDNのキャッシュサーバーも同じです。たくさんのWebコンテンツ(画像ファイルやHTMLファイルなど)を一時的に保管していますが、どのリクエストに対してどのコンテンツを返せばいいのかを区別する必要があります。その「区別するための情報」、それがキャッシュキーなんです!
もっと身近な例で言えば、お店のポイントカードや図書館の貸出カードのようなものです。
「ポイントカードをお持ちですか?」と聞かれてカードを提示すると、お店は「ああ、このお客様は〇〇さんね!」と識別してポイントを付けたり、割引を適用したりしますよね。
図書館で本を借りる時も、貸出カードの番号で「この本は〇〇さんが借りた」と管理します。
Cloud CDNでは、Webリクエスト(ユーザーが「このページを見たい!」と送る情報)の中から、どのコンテンツを返すべきかを識別するための「鍵」となる情報を取り出して、それをキャッシュキーとして使います。このキャッシュキーが全く同じであれば、CDNは「あ、これ前に誰かが要求したのと同じコンテンツだ! キャッシュしてあるから、すぐに返してあげよう!」と、オリジンサーバー(皆さんのWebサイトの本体サーバー)に問い合わせることなく、手元にあるキャッシュを返してくれるわけです。
GCP Cloud CDNのキャッシュキー、標準(デフォルト)構成を見てみよう!
Cloud CDNは、ユーザーからのHTTPリクエストに含まれる様々な情報を組み合わせて、自動的にキャッシュキーを生成しています。デフォルトでは、主に以下の要素を使ってキャッシュキーを作ります。
1. プロトコル (Protocol): http か https か、という情報です。
- 例:
https
2. ホスト名 (Host): どのドメイン名にアクセスしているか、という情報です。
- 例:
www.example.com
3. パス (Path): ドメイン名の後に続く、ファイルやディレクトリの場所を示す情報です。
- 例:
/images/logo.png
4. クエリパラメータ (Query Parameters): URLの末尾に「?」の後に続く「key=value」形式の情報です。
- 例:
?version=1.0&color=blue
例えば、ユーザーが「https://www.example.com/images/logo.png?version=1.0」というURLで画像をリクエストしたとしましょう。
この場合、デフォルトのキャッシュキーは、これら全ての要素を組み合わせて作られます。
- プロトコル:
https - ホスト名:
www.example.com - パス:
/images/logo.png - クエリパラメータ:
version=1.0
もし、別のユーザーが「https://www.example.com/images/logo.png?version=2.0」とリクエストしたらどうなるでしょう?
パスまでは同じですが、クエリパラメータの version が違いますよね。この場合、キャッシュキーも異なるものと判断され、CDNは新しいコンテンツとしてキャッシュを生成しようとします。
キャッシュキーをカスタマイズするって、どういうこと?
「え、じゃあ、URLが少しでも違ったら全部別のキャッシュになっちゃうの?」
はい、デフォルトではそうなります。でも、それが困る場合もあるんです。
例えば、以下のようなケースを考えてみてください。
- ケース1:同じコンテンツなのに、クエリパラメータが異なる場合
https://www.example.com/item.html?session_id=abchttps://www.example.com/item.html?session_id=xyz
この session_id はユーザーごとに変わる情報ですが、表示される item.html の内容は全く同じだとします。この場合、session_id の違いで別々のキャッシュが作られるのは、キャッシュの無駄ですよね?
- ケース2:複数のドメインで同じコンテンツを配信している場合
https://www.example.com/style.csshttps://example.jp/style.css
www.example.com と example.jp が同じWebサイトを指していて、style.css の中身が全く同じなのに、ホスト名が違うだけで別々のキャッシュが作られるのはもったいないですよね。
このような時に、「キャッシュキーをカスタマイズ」する出番です!
Cloud CDNでは、「この情報はキャッシュキーに含めないでね」「このヘッダーの情報もキャッシュキーの一部にしてね」といった指示を出すことで、キャッシュの識別方法を細かく調整できるんです。
先ほどの郵便配達の例で言えば、「〇〇番地△△号室の荷物は、たとえ部屋番号が違っても、同じ建物ならまとめて〇〇番地△△棟の荷物として扱っていいよ!」といった融通を利かせるようなイメージですね。これにより、もっと効率的にキャッシュを使い回すことができるようになります。
カスタマイズの構成要素を深掘り!
それでは、具体的にどのような要素をカスタマイズできるのか、一つずつ見ていきましょう。
プロトコル(Protocol)
デフォルトでは、http と https は異なるキャッシュキーとして扱われます。つまり、http://example.com/a.html と https://example.com/a.html は別々のキャッシュとして保存されます。
しかし、「うちは全部HTTPSにリダイレクトしてるから、HTTPでアクセスされても最終的にはHTTPSと同じコンテンツを返すんだよな…」という場合や、「HTTPとHTTPSで同じキャッシュを共有したい」というニーズもあるかもしれません。そのような場合は、プロトコルをキャッシュキーから除外することで、両方からのリクエストで同じキャッシュを利用できるようになります。
ホスト名(Host)
デフォルトでは、www.example.com と example.com は異なるキャッシュキーとして扱われます。
しかし、これらが同じWebサイトのコンテンツを指していて、かつ同じコンテンツを返す場合、ホスト名をキャッシュキーから除外することで、同じキャッシュを共有できるようになります。
複数のドメイン名で同じコンテンツを配信しているマルチドメイン運用の場合などに有効な設定ですね。
パス(Path)
これは基本的に、キャッシュキーに含めるべき必須要素です。
なぜなら、example.com/index.html と example.com/about.html は全く異なるコンテンツだからです。これを除外してしまうと、CDNは何を返せばいいのか分からなくなってしまいます。
ですので、パスは通常、そのままキャッシュキーの要素として残しておきます。
クエリパラメータ(Query Parameters)
ここが最もカスタマイズのニーズが高い部分かもしれません!
URLの ? の後に続く「key=value」の形式で表現されるクエリパラメータは、ユーザーの状態やトラッキング情報など、様々なデータを含みます。
例えば、
?session_id=abcdefg(セッションID)?utm_source=google&utm_medium=cpc(Google Analyticsなどのトラッキング情報)?_ga=2.123456789.123456789.123456789-123456789(Google AnalyticsのクライアントID)
これらは、ページのコンテンツ自体には影響しないことが多いですよね。なのに、これらのパラメータが少しでも違うと、CDNは「別のコンテンツだ!」と判断して、新しいキャッシュを作ってしまいます。結果として、キャッシュのヒット率が下がり、CDNのメリットが半減してしまう可能性があります。
ここでできるカスタマイズは主に二つです。
1. 特定のクエリパラメータをキャッシュキーから除外する(Blacklist):
session_idやutm_sourceなど、コンテンツに影響しないパラメータをリストアップして、キャッシュキーに含めないようにします。これにより、これらのパラメータが異なっても同じキャッシュが使われるようになります。
2. 特定のクエリパラメータのみをキャッシュキーに含める(Whitelist):
- 逆に、
version=1.0やlang=jaのように、コンテンツのバリエーションを切り替えるために必要なクエリパラメータだけを厳選してキャッシュキーに含めることもできます。それ以外のパラメータは全て無視されます。
この設定を適切に行うことで、キャッシュヒット率を大幅に向上させ、ユーザー体験の向上とオリジンサーバーへの負荷軽減に大きく貢献できます。
HTTPヘッダー(HTTP Headers)
HTTPヘッダーとは、Webリクエストやレスポンスの本体(コンテンツ)に付随する「メタ情報」のようなものです。
例えば、
User-Agent: ユーザーが使っているブラウザやOS、デバイスの種類(PC、スマホなど)を示す情報。Accept-Language: ユーザーが希望する言語(日本語、英語など)を示す情報。
これらは、コンテンツの表示内容を切り替えるために使われることがあります。
例えば、スマートフォンからのアクセスにはモバイル版の画像を、PCからのアクセスには高解像度の画像を配信したい場合。
また、日本語を希望するユーザーには日本語ページを、英語を希望するユーザーには英語ページを配信したい場合などですね。
このような場合、「User-Agent が異なるなら、別のキャッシュとして扱ってね」とか、「Accept-Language が異なるなら、別のキャッシュとして扱ってね」とCDNに指示を出すことができます。
これにより、同じURLでも、リクエストヘッダーに応じて異なるコンテンツをキャッシュし、適切に配信することが可能になります。
ただし、ヘッダーをキャッシュキーに含めすぎると、キャッシュのバリエーションが増えすぎてしまい、かえってキャッシュヒット率が下がる可能性もあるので注意が必要です。
必要なものだけを厳選することが大切です。
実践!Cloud CDN キャッシュキーのカスタマイズ設定例
それでは、実際にgcloudコマンドを使ってCloud CDNのキャッシュキーをカスタマイズする方法を見ていきましょう。
これらの設定は、Cloud CDNを有効にしたロードバランサーの「バックエンドサービス」に対して行います。
まずは、Cloud CDNを有効にしたバックエンドサービスを作成する基本コマンドです。
# まずはCloud CDNを有効にしたバックエンドサービスを作成します
# ここでは例として、東京リージョンのバックエンドバケットをオリジンとします
# 実際にはCompute Engineのインスタンスグループなどを指定します
gcloud compute backend-services create my-cdn-backend-service \
--protocol HTTP \
--port-name http \
--global \
--enable-cdn \
--cdn-policy "serve-while-stale=86400,default-ttl=3600,cache-max-age=86400" \
--description "CDN enabled backend service for my website"
キャッシュキーから特定のクエリパラメータを除外する例
コンテンツ自体には影響しない、session_id や utm_source といったトラッキング用のクエリパラメータをキャッシュキーから除外したい場合の設定です。
# バックエンドサービスを更新して、特定のクエリパラメータをキャッシュキーから除外します。
# 例: "session_id", "utm_source" はキャッシュキーに含めない
gcloud compute backend-services update my-cdn-backend-service \
--global \
--cdn-policy "cache-key-query-string-blacklist=session_id,utm_source" \
--description "CDN enabled backend service with specific query params blacklisted"
# 設定後、バックエンドサービスの詳細を確認して、変更が適用されたか確認できます
gcloud compute backend-services describe my-cdn-backend-service --global
この設定により、例えば https://example.com/page.html?session_id=abc と https://example.com/page.html?session_id=xyz は、同じ page.html のキャッシュとして扱われるようになります。キャッシュヒット率アップに直結しますね!
キャッシュキーに特定のHTTPヘッダーを含める例
デバイスの種類(PC/スマホ)によって異なるコンテンツを配信したい場合など、User-Agent ヘッダーをキャッシュキーに含めることで、User-Agent ごとに別のキャッシュを生成させることができます。
# バックエンドサービスを更新して、特定のHTTPヘッダーをキャッシュキーに含めます。
# 例: User-Agent ヘッダーを含めることで、デバイス種別に応じたキャッシュを生成
gcloud compute backend-services update my-cdn-backend-service \
--global \
--cdn-policy "cache-key-include-http-headers=User-Agent" \
--description "CDN enabled backend service with User-Agent in cache key"
# 設定後、バックエンドサービスの詳細を確認
gcloud compute backend-services describe my-cdn-backend-service --global
この設定をすると、PCからのアクセスとスマートフォンからのアクセスで、たとえ同じURLでも、それぞれ別のキャッシュが作られ、適切なコンテンツが返されるようになります。
キャッシュキーのホスト名やプロトコルを含めない例
複数のドメイン名で同じコンテンツを共有したい場合や、HTTPとHTTPSで同じキャッシュを利用したい場合の設定です。
# ホスト名をキャッシュキーから除外する例
# これにより、example.com と www.example.com で同じコンテンツを共有できます
gcloud compute backend-services update my-cdn-backend-service \
--global \
--cdn-policy "cache-key-include-host=False" \
--description "CDN enabled backend service without host in cache key"
# プロトコルをキャッシュキーから除外する例
# これにより、HTTP と HTTPS で同じコンテンツを共有できます
gcloud compute backend-services update my-cdn-backend-service \
--global \
--cdn-policy "cache-key-include-protocol=False" \
--description "CDN enabled backend service without protocol in cache key"
# 両方を一度に設定することも可能です
gcloud compute backend-services update my-cdn-backend-service \
--global \
--cdn-policy "cache-key-include-host=False,cache-key-include-protocol=False" \
--description "CDN enabled backend service without host and protocol in cache key"
# 設定後、バックエンドサービスの詳細を確認
gcloud compute backend-services describe my-cdn-backend-service --global
これらの設定は、cdn-policy の中にカンマ区切りで複数指定できます。
ご自身のWebサイトの特性に合わせて、最適な設定を見つけてみてくださいね。
よくある疑問・注意点
カスタマイズしすぎると、かえってキャッシュヒット率が下がる?
はい、その通りです!
キャッシュキーに含める要素を増やしすぎると、少しのリクエストの違いでも「別のコンテンツ」と判断されてしまい、キャッシュのバリエーションが爆発的に増えてしまいます。結果として、キャッシュのヒット率が下がり、CDNの恩恵を受けにくくなる可能性があります。
必要最低限の要素だけをカスタマイズすることが重要です。
セキュリティやプライバシーへの影響は?
特に、session_id のようなユーザー固有の情報をキャッシュキーに含めてしまうと、他のユーザーにその情報を共有してしまう可能性があり、セキュリティ上の問題につながりかねません。
もし含める必要がないのであれば、必ずキャッシュキーから除外するようにしましょう。
設定変更後のテストは必須!
キャッシュキーの設定を変更したら、必ず様々なパターンでアクセスしてみて、意図した通りにキャッシュが効いているか、または正しくコンテンツが切り替わっているかをテストしてください。
GCPのCloud CDNでは、レスポンスヘッダーに X-Cache のような情報が含まれるので、それを見てキャッシュがヒットしたかどうかを確認できます。
まとめ
皆さん、今日の「キャッシュキー」のお話、いかがでしたでしょうか?
Cloud CDNのキャッシュキーは、まるでWebコンテンツを識別するための「デジタルな鍵」のようなものです。この鍵の構成要素を理解し、適切にカスタマイズすることで、CDNのパフォーマンスを最大限に引き出し、ユーザー体験を劇的に向上させることができます。
- デフォルトでは、プロトコル、ホスト名、パス、クエリパラメータがキャッシュキーになります。
- カスタマイズすることで、コンテンツに影響しないクエリパラメータを除外したり、特定のヘッダーをキーに含めたりできます。
- ただし、カスタマイズしすぎるとキャッシュヒット率が下がる可能性もあるので、バランスが重要です。
最初は少し難しく感じるかもしれませんが、これはWebサービスのパフォーマンス改善において非常に重要なスキルです。
ぜひ、ご自身のサービスでCloud CDNを使う際には、このキャッシュキーのカスタマイズを試してみてください。きっと、皆さんのWebサイトがよりサクサク快適になるはずです!
それでは、また次回の記事でお会いしましょう!
コメント