🚀

Cloud CDN のキャッシュと動的圧縮でコンテンツ配信のパフォーマンスを向上しよう

2022/12/03に公開

みなさん Cloud CDN、使ってますか?
この記事は Google Cloud Japan Advent Calendar 2022(今から始めるGoogle Cloud) の3日目の記事です。

Cloud CDN を使用するとキャッシュ機能によりユーザーへのコンテンツ配信を高速化できるだけでなく、サーバーの負荷やネットワーク転送量を削減できるといったメリットがあります。この Cloud CDN のメリットを更に拡大する機能の1つが、動的圧縮です。動的圧縮は Cloud CDN から配信されるコンテンツをクライアントとの間で自動的に圧縮します。この記事では、Cloud CDN および動的圧縮の設定方法と、これによる効果を確認したいと思います。

Cloud CDN の動的圧縮の仕組み

最初に動的圧縮の仕組みを理解しましょう。動的圧縮はユーザーのWeb ブラウザと Cloud CDN の間でコンテンツを圧縮します。

まず、Web ブラウザは HTTP GET リクエストを送信する際、対応している圧縮方式のリストを Accept-Encoding ヘッダに含めてサーバへ送信します。これを受け取った Cloud CDN は、そのうちの1つを選択して Content-Encoding ヘッダに含め、HTTP レスポンスを圧縮してブラウザへ送信します。

Cloud CDN が対応している圧縮方式は、Brotli (br) と gzip の2つです。(2022年12月現在)
また、Cloud CDN が自動で圧縮するコンテンツタイプは HTML や CSS、Javascript、JSON などのテキストファイルであり、画像や動画のコンテンツはすでに圧縮されているため Cloud CDN では圧縮されません。

実際に使ってみよう

それでは実際に Cloud CDN を使用して効果を確認してみましょう!
Cloud CDN のバックエンドには GCE のインスタンスグループや、GAE、Cloud Run、Cloud Functions のサーバレス NEG、または Cloud Storage を選択することができます。今回は、Cloud Run でバックエンド サービスを構成することにします。また、CDN の効果を確認しやすいように、地球の裏側のサンパウロ リージョンを選択します。

(1) バックエンドサービスを作成する

まずはバックエンドサービス用の docker イメージを作成します。ここでは nginx の docker イメージをベースに、2MB 程度の js ファイルを配置することで CDN の効果を検証しやすいようにしています。

フォルダ構成
.
├ Dockerfile
└ sample.js
Dockerfile
FROM 'nginx:latest'
COPY sample.js /usr/share/nginx/html/
RUN service nginx start

この docker イメージを Artifact Registory に登録し、Cloud Run にデプロイします。

export PROJECTID=[プロジェクトIDを指定]
gcloud artifacts repositories create cdn-demo-repo \
     --repository-format=docker \
     --location=asia-northeast1
gcloud auth configure-docker asia-northeast1-docker.pkg.dev
docker image build -t "asia-northeast1-docker.pkg.dev/${PROJECTID}/cdn-demo-repo/nginx" .
docker image push "asia-northeast1-docker.pkg.dev/${PROJECTID}/cdn-demo-repo/nginx"
gcloud run deploy nginx-service \
     --image="asia-northeast1-docker.pkg.dev/${PROJECTID}/cdn-demo-repo/nginx" \
     --region=southamerica-east1 \
     --allow-unauthenticated \
     --port 80

これで Cloud Run に nginx の Web サーバをデプロイすることができました。

(2) バックエンドサービスを LB 配下に配置する

次に、作成した Web サーバーを LB 配下に配置します。Cloud CDN の動的圧縮に対応しているグローバル外部 HTTP(S) ロードバランサ(従来)を作成します。(loadBalancingSchemeEXTERNAL を指定します)

gcloud compute network-endpoint-groups create nginx-neg \
     --region=southamerica-east1 \
     --network-endpoint-type=serverless  \
     --cloud-run-service=nginx-service
gcloud compute backend-services create cdn-backend \
     --load-balancing-scheme=EXTERNAL \
     --global
gcloud compute backend-services add-backend cdn-backend \
     --global \
     --network-endpoint-group=nginx-neg \
     --network-endpoint-group-region=southamerica-east1
gcloud compute url-maps create http-lb \
     --default-service cdn-backend 
gcloud compute target-http-proxies create http-lb-proxy \
     --url-map=http-lb
gcloud compute forwarding-rules create http-lb-forwarding-rule \
     --load-balancing-scheme=EXTERNAL \
     --network-tier=PREMIUM \
     --target-http-proxy=http-lb-proxy \
     --global \
     --ports=80

これで準備は完了です。次に進む前に、LB の External IP アドレスを確認しておきましょう。

gcloud compute forwarding-rules list
出力結果
NAME: http-lb-forwarding-rule
REGION:
IP_ADDRESS: [LBのExternal IPアドレス]
IP_PROTOCOL: TCP
TARGET: http-lb-proxy

(3) CDN キャッシュの効果を確認する

まずは、Cloud CDN を有効化する前のパフォーマンスを確認してみましょう。WEB ブラウザで、http://[LBのExternal IPアドレス]/sample.js を取得してみます。筆者の環境で Chrome のデベロッパーツールを使用して計測すると、リクエストの送信からコンテンツの受信完了まで 2.12 秒でした。

それでは次に、Cloud CDN を有効化してパフォーマンスを確認してみます。

gcloud compute backend-services update cdn-backend --enable-cdn --global

先ほどと同じコンテンツにアクセスすると、初回は Cloud CDN にキャッシュがないため先程同様に 2 秒近くかかります。初回アクセスで Cloud CDN にコンテンツがキャッシュされた後に再度アクセスすると、リクエストの送信からコンテンツの受信完了まで今度は 294 ミリ秒となりました。

検証するクライアントのネットワーク環境にも結果は左右されますので、是非皆様の環境でも確認していただければと思います!

(4) 動的圧縮の効果を確認する

次は動的圧縮の効果を確認してみましょう。まずは、動的圧縮を設定する前の Web サーバーのレスポンスを確認します。こちらもChrome のデベロッパーツールで確認することができます。

Web ブラウザが受信したコンテンツのサイズは 2,106,740 バイトです。

それでは Cloud CDN の動的圧縮を有効化します。

gcloud compute backend-services update cdn-backend \
     --compression-mode=AUTOMATIC\
     --global

先ほどと同じコンテンツにアクセスすると、受信したコンテンツのサイズは 548,828 バイトまで圧縮されました。

レスポンスヘッダーの Content-Encoding: gzipVary: Accept-Encoding といった箇所からも、コンテンツが圧縮されていることが分かります。またリクエストの送信からコンテンツの受信完了までの時間も 143 ミリ秒と、動的圧縮を使わない場合のおよそ半分、さらに CDN を使わない場合の 1/15 程度まで短縮しました。

こちらの圧縮率も対象のファイルによって結果は左右されますので、是非お試しいただければと思います!

(5)コスト削減効果を確認する

パフォーマンスの改善効果は(3)(4)のステップで是非体感いただければと思いますが、ここではネットワークのコスト削減効果にも触れておきたいと思います。

Cloud CDN を使わず Web サーバーからコンテンツを配信する場合、インターネット下り(外向き)料金は 1GB あたり 0.12〜0.14 ドルです。(東京リージョンで Premium Tier の場合)
Cloud CDN を使ってコンテンツを配信する場合、キャッシュヒットした際の下り(外向き)料金は 1GB あたり 0.05〜0.09 ドルです。(アジア太平洋への配信の場合)
そして動的圧縮を有効にする場合、追加のコストはかかりません! ネットワーク転送量が削減された分だけコストの削減が見込めます。

なお上記は 2022 年 12 月時点の情報であり、LB やバックエンドサービスの費用が含まれないことにご注意ください。実際のプロジェクトにおける試算では、キャッシュヒットの割合やキャッシュ不可コンテンツの割合、平均的な圧縮率、配信先の地域についても考慮した上で試算を行ってください。
https://cloud.google.com/cdn/pricing?hl=ja

まとめ

この記事では、Cloud CDN と動的圧縮の仕組みをお伝えした上で、実際に使って効果を実感するためのステップをご紹介しました。LB とバックエンドサーバで構成された Web サービスをすでに運用中の環境であれば、それぞれコマンド1つで機能を有効化できることをご理解いただけたかと思います。

そして数分で有効化できる Cloud CDN と動的圧縮によって得られるメリットについてもご理解いただけたでしょうか。ユーザーへのコンテンツ配信の高速化、サーバーの負荷やネットワーク転送量を削減、そしてコスト削減といった効果を期待することができます。

この記事をご覧になった皆様に、Cloud CDN と動的圧縮をご検討いただければ幸いです!

明日からも続々と記事が公開される Google Cloud Japan Advent Calendar 2022 をよろしくお願いします!

参考リンク

https://cloud.google.com/cdn/docs/overview?hl=ja
https://cloud.google.com/cdn/docs/dynamic-compression?hl=ja

Google Cloud Japan

Discussion