こんにちは!SREとして日夜クラウドのインフラと格闘している筆者です。
皆さんは、Webサイトやアプリを運営していて「おっと、大変だ! 存在しないページ(404エラー)に大量のアクセスが押し寄せているぞ……!」と、オリジンサーバー(実際のアプリが動いているサーバー)のCPU使用率やエラーログが跳ね上がって冷や汗をかいた経験はありませんか?
「サーバーにデータが無いんだから、無いって答えるだけなのに、なんでそんなにサーバーが重くなるの?」と不思議に思いますよね。実は、その「無い」という返事(エラーレスポンス)を毎回オリジンサーバーが自力で計算して返していると、それだけでサーバーの体力がゴリゴリ削られてしまうんです。
今回は、Google Cloud(GCP)の強力な配信エンジンである Cloud CDN の機能の一つ、「Negative Caching(ネガティブキャッシュ)」 について、現実世界の仕組みに例えながら、一歩ずつ優しく紐解いていきたいと思います。
難解な専門用語は置いておいて、まずはリラックスして読み進めてくださいね!
—
1. 郵便配達と「あて先不明」のルールに例えてみよう
突然ですが、あなたが近所の郵便局のベテラン配達員だと思って想像してみてください。
ある日、宛先が適当に書かれた手紙の山があなたのところにやってきました。一件一件、宛先の家を回って「こんな人いませんよね?」と確認しに行くのは、めちゃくちゃ大変ですよね。足も棒になるし、家の人もうっとうしがるでしょう。
常識的な配達員なら、一度その宛先を調べて「ああ、この名前のお宅はこの町には引っ越してきちゃったからもう無いんだな」と分かった時点で、メモ帳にこう書き留めるはずです。
> 「〇丁目〇番地宛の手紙は、今のところ宛先不明なので、しばらくは配達に行かずに『お留守です(あるいは存在しません)』とその場で突っ返そう!」
これが、まさに Negative Caching(ネガティブキャッシュ) の考え方そのものです。
通常の CDN(Cloud CDN)は、「この画像きれいですね」「このページ素敵ですね」という正常なデータ(ポジティブなデータ)をキャッシュして、ユーザーの近くの配達拠点(エッジサーバー)に置いておきます。
一方のネガティブキャッシュは、「このページはありませんでした(404)」「今ちょっとサーバーが疲れてお休み中です(502など)」という、ちょっと不名誉なエラーの返事(ネガティブなデータ)をあえて一時的にキャッシュする仕組みです。
これにより、世界中から「このページある?」と意地悪な質問(あるいはバグによるアクセス)が大量に押し寄せても、オリジンサーバーのところまで行かずに、手前のエッジサーバーが「あ、それさっきも聞かれたけど無いよ!」と秒速でシャットアウトしてくれるわけですね。サーバーの延命には欠かせない、いぶし銀の機能なんです。
—
2. Cloud CDNのネガティブキャッシュが守る世界
GCPの環境では、外部HTTP(S) ロードバランサー(Global External HTTP(S) Load Balancer)のバックエンドサービスに Cloud CDN を組み合わせます。
ユーザーがGCPのエッジ(世界中に散らばるGoogleの拠点)にアクセスしたとき、以下のようなドラマが裏で繰り広げられています。
1. ユーザーが https://example.com/not-found-page にアクセスする。
2. エッジサーバーはオリジンサーバーにデータを取りに行くが、オリジンは「そんなページないよ!」と 404 Not Found を返す。
3. Cloud CDNのネガティブキャッシュが有効になっていると、この 404 レスポンスをエッジ側で一定時間(TTL)だけ「おぼえておこう」とキープする。
4. 次に別のユーザー(あるいは同じボット)が同じ存在しないページにアクセスしてきても、オリジンサーバーには1ミリもリクエストが飛ばず、エッジサーバーが即座に 404 を返す。
これで、オリジンサーバーは無駄な処理から解放され、本当に大切なユーザーの処理に集中できるようになるというわけです。
—
3. どのエラーコードがキャッシュの対象になるの?
「じゃあ、どんなエラーでもとりあえず全部キャッシュしちゃえばいいの?」と思われるかもしれませんが、それはちょっと危険です。
例えば、一時的な通信の揺れで起きたエラーなのか、本当にページが存在しないのかによって、おぼえておくべき時間は変えたほうが賢明ですよね。
Cloud CDNでは、主に以下のようなHTTPステータスコードをネガティブキャッシュの対象として設定・制御することができます。
404 Not Found(ページが存在しない)410 Gone(ページが完全に消滅した)502 Bad Gateway(オリジンを手伝う中継サーバーがおかしくなった)503 Service Unavailable(オリジンが満杯またはメンテナンス中)504 Gateway Timeout(オリジンの返事がタイムアウトした)
特に 404 や 410 のような「どうあがいても存在しない」ことが確実なエラーは、ネガティブキャッシュと非常に相性が良いです。
—
4. 実践!Cloud CDNでネガティブキャッシュを設定してみよう
それでは、実際のインフラ構築の現場でどのように設定するのか、Google Cloudのコマンドラインツール(gcloud)を例に見ていきましょう。一歩ずつ設定すれば難しくありませんよ。
今回は、バックエンドサービスに対して「ネガティブキャッシュを有効にし、404エラーの場合は30秒間キャッシュする」という設定を行ってみます。
gcloudコマンドによる設定例
# すでに作成済みのバックエンドサービス名(例: my-web-backend-service)に対して、
# ネガティブキャッシュを有効化し、キャッシュのルールを追加します。
# 1. Cloud CDN自体の有効化とネガティブキャッシュの有効化
gcloud compute backend-services update my-web-backend-service \
--global \
--enable-cdn
# 2. 404エラー(Not Found)が発生したときに、30秒間エッジでキャッシュする設定を追加
gcloud compute backend-services update my-web-backend-service \
--global \
--set-negative-caching-policies=404=30
設定値のポイント
--enable-cdn: これでロードバランサーのバックエンドにCloud CDNの魔法がかかります。--set-negative-caching-policies: ここが肝心ですね。404=30と指定することで、「404が返ってきたら、30秒間はエッジでその結果を保持しなさい」という命令を与えています。- TTL(Time To Live)の秒数は、システムの特性に合わせて調整します。あまり長くしすぎると、もし急いでページを復旧させたときに「まだ無いって言われるんだけど!」というタイムラグが発生してしまうので、バランスが大切です。
—
5. 現場のSREが教える、設定時の注意点と落とし穴
最後に、実際に現場でこの機能を使うときに、思わぬハマりどころにならないための「SREからのアドバイス」をいくつかお伝えしておきますね。
① TTLを長くしすぎないこと
先ほども少し触れましたが、ネガティブキャッシュのTTLを例えば「1時間(3600秒)」などに設定してしまうと、デバッグ中に「あ、ファイルを置き忘れてた!アップロードしよ」と直しても、1時間の間は世界中のユーザーに「エラーページ」が配信され続けてしまいます。「数秒〜せいぜい数十秒、長くても数分」程度から始めるのが安全です。
② クエリパラメータの扱いに注意する
例えば、ユーザーが適当なパラメータ(?ref=twitter や ?foo=bar など)をくっつけて存在しないページにアクセスしてきた場合、もしキャッシュのキー設計が甘いと、パラメータ違いの「無いページ」のキャッシュがエッジに溢れかえってしまいます(キャッシュ汚染)。Cloud CDNのキャッシュキー設定もあわせて確認しておきましょう。
—
まとめ
いかがでしたでしょうか?
今回は、Cloud CDNの「ネガティブキャッシュ」という、ちょっと玄人好みな機能を現実世界の郵便配達に例えて解説してみました。
- ネガティブキャッシュとは、「エラーの返事」をエッジサーバーで一時的に記憶して使い回す仕組みである。
- オリジンサーバーへの不要なトラフィック負荷(特に404の嵐など)を劇的に軽減できる。
- 設定は
gcloudコマンドなどでシンプルに行えるが、TTL(時間)の長さには注意が必要。
クラウドインフラやネットワークの世界は、一見すると複雑な言葉の羅列に見えますが、本質を紐解けば私たちが普段暮らしている社会の仕組みとよく似ています。
「なぜこの機能が必要なのか」「どこでどうパケットやリクエストが節約されているのか」をイメージできるようになると、インフラを触るのがぐっと楽しくなりますよ。
それでは、また次回の技術解説でお会いしましょう!皆さんのクラウドライフが快適なものでありますように!
コメント