- Cloud CDNはGoogle のグローバルエッジネットワークを活用した高性能コンテンツ配信サービスで、レイテンシを大幅に削減できる
- Cache-Controlヘッダーの適切な設計とキャッシュキー最適化で、キャッシュヒット率90%以上を実現可能
- SES市場でCDN・パフォーマンス最適化スキルの需要が高まっており、月額75〜100万円クラスの案件に直結する
「Webサイトの表示速度が遅くて、ユーザー離脱率が高い…」「オリジンサーバーへの負荷が集中して、ピーク時にレスポンスが悪化する…」——SES現場でWebパフォーマンスの改善を求められることは多いのではないでしょうか。
結論から言うと、Google Cloud CDNを適切に設計・最適化すれば、Webサイトの表示速度を大幅に改善しながら、オリジンサーバーの負荷とコストを削減できます。Googleのグローバルエッジネットワーク(200以上のPoP)を活用し、ユーザーに最も近い場所からコンテンツを配信します。
この記事はGoogle Cloud完全攻略シリーズとして、Cloud CDNのパフォーマンス最適化を実践的に解説します。
- Cloud CDNの基本概念とアーキテクチャ
- キャッシュ設計のベストプラクティス(Cache-Controlヘッダー)
- キャッシュキーの最適化によるヒット率向上
- Cloud Armorとの連携によるセキュリティ強化
- パフォーマンス監視とコスト最適化
Cloud CDNの基本概念
Cloud CDNのアーキテクチャ
Cloud CDNは、Google Cloud Load Balancingと統合された形で動作します。
ユーザー(東京)
│
▼
Google Edge POP(東京)
│ ← キャッシュヒット → そのままレスポンス
│ ← キャッシュミス ↓
▼
Google Cloud Load Balancer
│
▼
バックエンドサービス
(Cloud Run / GKE / GCE / Cloud Storage)
他社CDNとの比較
| 機能 | Cloud CDN | CloudFront | Cloudflare |
|---|---|---|---|
| エッジPOP数 | 200+ | 600+ | 310+ |
| HTTP/3対応 | ◎ | ◎ | ◎ |
| WebSocket対応 | ○ | ◎ | ◎ |
| WAF統合 | Cloud Armor | AWS WAF | 標準搭載 |
| 料金(GB単価) | $0.08〜 | $0.085〜 | 無制限プランあり |
| GCP統合 | ◎ | △ | ○ |
| カスタムオリジン | ◎ | ◎ | ◎ |
Cloud CDNの最大の強みは、Google Cloud Load Balancingとのシームレスな統合とGoogleのプレミアムネットワークを活用した低レイテンシです。
Cloud CDNの有効化
Cloud CDNはロードバランサーのバックエンドサービスで有効化します。
# バックエンドサービスでCDNを有効化
gcloud compute backend-services update my-backend-service \
--enable-cdn \
--cache-mode=CACHE_ALL_STATIC \
--default-ttl=3600 \
--max-ttl=86400 \
--client-ttl=3600 \
--global
キャッシュ設計のベストプラクティス
Cache-Controlヘッダーの設計
キャッシュ設計はCDNパフォーマンスの最も重要な要素です。コンテンツの種類ごとに適切なCache-Controlヘッダーを設定します。
# Nginx設定例
# 静的アセット(JS/CSS/画像)- 長期キャッシュ + immutable
location ~* \.(js|css|png|jpg|jpeg|gif|webp|svg|ico|woff2)$ {
add_header Cache-Control "public, max-age=31536000, immutable";
add_header Vary "Accept-Encoding";
}
# HTMLページ - 短期キャッシュ + 再検証
location ~* \.html$ {
add_header Cache-Control "public, max-age=300, stale-while-revalidate=86400";
}
# APIレスポンス - キャッシュしない
location /api/ {
add_header Cache-Control "no-store, no-cache, must-revalidate";
add_header Pragma "no-cache";
}
# フィードデータ - 中期キャッシュ
location ~* \.(json|xml|rss|atom)$ {
add_header Cache-Control "public, max-age=900, stale-while-revalidate=3600";
}
コンテンツ別キャッシュ戦略
| コンテンツタイプ | max-age | stale-while-revalidate | 備考 |
|---|---|---|---|
| JS/CSS(ハッシュ付き) | 1年 | - | immutable指定 |
| 画像(ハッシュ付き) | 1年 | - | immutable指定 |
| HTMLページ | 5分 | 24時間 | 常に新鮮さを確保 |
| APIレスポンス | 0 | - | no-storeで完全無効化 |
| フォント | 1年 | - | immutable指定 |
| OGP画像 | 1時間 | 24時間 | SNSクローラー対応 |
キャッシュモードの使い分け
Cloud CDNには3つのキャッシュモードがあります。
# Terraform設定
# モード1: CACHE_ALL_STATIC(推奨)
# 静的コンテンツを自動検出してキャッシュ
resource "google_compute_backend_service" "static" {
name = "static-backend"
cdn_policy {
cache_mode = "CACHE_ALL_STATIC"
default_ttl = 3600 # 1時間
max_ttl = 86400 # 24時間
client_ttl = 3600 # 1時間
}
}
# モード2: USE_ORIGIN_HEADERS
# オリジンのCache-Controlヘッダーに従う(最も柔軟)
resource "google_compute_backend_service" "dynamic" {
name = "dynamic-backend"
cdn_policy {
cache_mode = "USE_ORIGIN_HEADERS"
}
}
# モード3: FORCE_CACHE_ALL
# すべてのレスポンスを強制キャッシュ(注意して使用)
resource "google_compute_backend_service" "aggressive" {
name = "aggressive-cache-backend"
cdn_policy {
cache_mode = "FORCE_CACHE_ALL"
default_ttl = 300
max_ttl = 3600
}
}
キャッシュキーの最適化
デフォルトのキャッシュキー
Cloud CDNのデフォルトキャッシュキーは以下の要素で構成されます。
URI + ホスト + クエリパラメータ(全て)
これでは、不要なパラメータ(トラッキングIDなど)の違いでキャッシュが分割されてしまいます。
キャッシュキーのカスタマイズ
resource "google_compute_backend_service" "optimized" {
name = "optimized-backend"
cdn_policy {
cache_mode = "CACHE_ALL_STATIC"
cache_key_policy {
# ホスト名をキーに含める
include_host = true
# プロトコル(HTTP/HTTPS)は含めない
include_protocol = false
# クエリパラメータのホワイトリスト
include_query_string = true
query_string_whitelist = [
"page",
"sort",
"category",
"lang",
]
# utm_*, fbclid, gclid などの追跡パラメータを無視
}
}
}
クエリパラメータの影響を検証
# キャッシュヒット率を確認
gcloud logging read '
resource.type="http_load_balancer"
AND httpRequest.requestUrl:"example.com"
AND jsonPayload.cacheHit=true
' --limit=100 --format="json" | jq '.[] | .httpRequest.requestUrl'
# キャッシュヒット率の計算
gcloud logging read '
resource.type="http_load_balancer"
AND httpRequest.requestUrl:"example.com"
' --limit=10000 --format="json" | jq '
[.[] | .jsonPayload.cacheHit] |
{ total: length, hits: [.[] | select(. == true)] | length } |
. + { hit_rate: (.hits / .total * 100 | tostring + "%") }
'

Signed URLとSigned Cookie
認証付きコンテンツ配信
プレミアムコンテンツや認証が必要なアセットの配信には、Signed URLまたはSigned Cookieを使用します。
// signed-url-generator.ts
import { Storage } from '@google-cloud/storage';
import crypto from 'crypto';
const storage = new Storage();
// Cloud CDN Signed URL の生成
function generateSignedUrl(
urlPrefix: string,
keyName: string,
key: Buffer,
expirationTime: Date
): string {
const urlPrefixEncoded = Buffer.from(urlPrefix).toString('base64url');
const expiration = Math.floor(expirationTime.getTime() / 1000);
const signedUrlInput = `URLPrefix=${urlPrefixEncoded}&Expires=${expiration}&KeyName=${keyName}`;
const signature = crypto
.createHmac('sha1', key)
.update(signedUrlInput)
.digest('base64url');
return `${urlPrefix}?${signedUrlInput}&Signature=${signature}`;
}
// 使用例
const keyName = 'my-cdn-key';
const key = Buffer.from(process.env.CDN_SIGNING_KEY!, 'base64');
const expiration = new Date(Date.now() + 3600 * 1000); // 1時間後
const signedUrl = generateSignedUrl(
'https://cdn.example.com/premium/video.mp4',
keyName,
key,
expiration
);
console.log('Signed URL:', signedUrl);
Signed Cookieでのセッション認証
// signed-cookie-generator.ts
function generateSignedCookie(
urlPrefix: string,
keyName: string,
key: Buffer,
expirationTime: Date
): Record<string, string> {
const urlPrefixEncoded = Buffer.from(urlPrefix).toString('base64url');
const expiration = Math.floor(expirationTime.getTime() / 1000);
const signedInput = `URLPrefix=${urlPrefixEncoded}&Expires=${expiration}&KeyName=${keyName}`;
const signature = crypto
.createHmac('sha1', key)
.update(signedInput)
.digest('base64url');
return {
'Cloud-CDN-Cookie': `${signedInput}&Signature=${signature}`,
};
}
Cloud Armorとの連携
DDoS防御とWAFの統合
Cloud CDNとCloud Armorを組み合わせることで、CDNレイヤーでのセキュリティ防御を実現します。
# Cloud Armor セキュリティポリシー
resource "google_compute_security_policy" "cdn_protection" {
name = "cdn-protection-policy"
# Rate Limiting
rule {
action = "throttle"
priority = 1000
match {
versioned_expr = "SRC_IPS_V1"
config {
src_ip_ranges = ["*"]
}
}
rate_limit_options {
conform_action = "allow"
exceed_action = "deny(429)"
rate_limit_threshold {
count = 100
interval_sec = 60
}
}
}
# 地域制限(日本とアメリカのみ許可)
rule {
action = "deny(403)"
priority = 2000
match {
expr {
expression = "!inRegion(origin.region_code, 'JP', 'US')"
}
}
}
# SQLインジェクション防御
rule {
action = "deny(403)"
priority = 3000
match {
expr {
expression = "evaluatePreconfiguredWaf('sqli-v33-stable', {'sensitivity': 1})"
}
}
}
# XSS防御
rule {
action = "deny(403)"
priority = 3001
match {
expr {
expression = "evaluatePreconfiguredWaf('xss-v33-stable', {'sensitivity': 1})"
}
}
}
# デフォルト許可
rule {
action = "allow"
priority = 2147483647
match {
versioned_expr = "SRC_IPS_V1"
config {
src_ip_ranges = ["*"]
}
}
}
}
Cloud Armorの詳細は「Google Cloud Cloud Armor WAFガイド」を参照してください。
パフォーマンス監視
Cloud CDNダッシュボードの設計
Cloud Monitoringで以下のメトリクスを監視します。
# 監視すべきメトリクス
metrics:
- name: キャッシュヒット率
metric: loadbalancing.googleapis.com/https/backend_request_count
filter: cache_result = "HIT" OR cache_result = "MISS"
alert_threshold: "ヒット率80%以下"
- name: CDNレイテンシ
metric: loadbalancing.googleapis.com/https/total_latencies
alert_threshold: "p95 > 200ms"
- name: エラーレート
metric: loadbalancing.googleapis.com/https/backend_request_count
filter: response_code_class >= 500
alert_threshold: "5xx率 > 1%"
- name: バイト配信量
metric: loadbalancing.googleapis.com/https/response_bytes_count
description: "トラフィック量の推移"
キャッシュヒット率の最適化
# キャッシュ統計の確認
gcloud compute backend-services get-health my-backend \
--global --format="json"
# キャッシュ無効化(パージ)
gcloud compute url-maps invalidate-cdn-cache my-url-map \
--path="/articles/*" \
--global
# 特定パスのキャッシュ無効化
gcloud compute url-maps invalidate-cdn-cache my-url-map \
--path="/api/v1/products" \
--global
コスト最適化
Cloud CDNの料金体系
| 料金項目 | 単価(アジア太平洋) |
|---|---|
| キャッシュ配信(0-10TB/月) | $0.09/GB |
| キャッシュ配信(10-150TB/月) | $0.06/GB |
| キャッシュフィル(オリジン取得) | $0.08/GB |
| キャッシュ無効化 | 無料(月100回まで) |
| HTTPリクエスト | $0.0075/10,000リクエスト |
コスト削減のベストプラクティス
- キャッシュヒット率を最大化:Cache-Controlヘッダーとキャッシュキーの最適化
- 圧縮の有効化:Brotli/gzip圧縮で転送量を削減
- 画像の最適化:WebP/AVIFフォーマットの活用
- 不要なバリエーションを削除:キャッシュキーから不要なパラメータを除外
# 圧縮設定
resource "google_compute_backend_service" "compressed" {
name = "compressed-backend"
cdn_policy {
cache_mode = "CACHE_ALL_STATIC"
# 圧縮を有効化
cache_key_policy {
include_host = true
include_protocol = false
include_query_string = true
query_string_whitelist = ["page", "sort"]
}
}
compression_mode = "AUTOMATIC"
log_config {
enable = true
sample_rate = 0.1
}
}
月額コスト試算例
想定:月間100万PV、平均ページサイズ2MB
キャッシュヒット率90%の場合:
CDN配信: 100万 × 2MB × 90% = 1,800GB × $0.09 = $162
オリジン取得: 100万 × 2MB × 10% = 200GB × $0.08 = $16
リクエスト: 100万 × $0.0075/10,000 = $0.75
合計: 約$179/月(約27,000円)
キャッシュヒット率50%の場合:
CDN配信: 100万 × 2MB × 50% = 1,000GB × $0.09 = $90
オリジン取得: 100万 × 2MB × 50% = 1,000GB × $0.08 = $80
合計: 約$171/月 + オリジンサーバー負荷大
キャッシュヒット率90%の方がCDNコスト自体はやや高いですが、オリジンサーバーの負荷が80%削減されるため、総合的なコストは大幅に下がります。
Terraformでのフル構築
完全なCDN構成
# Cloud CDN + Load Balancer + Cloud Armor の完全構成
# ロードバランサーのIPアドレス
resource "google_compute_global_address" "cdn_ip" {
name = "${var.project}-cdn-ip"
}
# SSL証明書(マネージド)
resource "google_compute_managed_ssl_certificate" "cdn_cert" {
name = "${var.project}-cdn-cert"
managed {
domains = [var.domain]
}
}
# URL Map
resource "google_compute_url_map" "cdn" {
name = "${var.project}-cdn-url-map"
default_service = google_compute_backend_service.app.id
host_rule {
hosts = [var.domain]
path_matcher = "main"
}
path_matcher {
name = "main"
default_service = google_compute_backend_service.app.id
path_rule {
paths = ["/static/*", "/assets/*"]
service = google_compute_backend_bucket.static.id
}
path_rule {
paths = ["/api/*"]
service = google_compute_backend_service.api.id
}
}
}
# 静的アセット用バックエンドバケット
resource "google_compute_backend_bucket" "static" {
name = "${var.project}-static-bucket"
bucket_name = google_storage_bucket.static.name
enable_cdn = true
cdn_policy {
cache_mode = "CACHE_ALL_STATIC"
default_ttl = 86400
max_ttl = 604800
signed_url_cache_max_age_sec = 3600
}
}
# アプリケーション用バックエンドサービス
resource "google_compute_backend_service" "app" {
name = "${var.project}-app-backend"
protocol = "HTTPS"
timeout_sec = 30
enable_cdn = true
security_policy = google_compute_security_policy.cdn_protection.id
compression_mode = "AUTOMATIC"
cdn_policy {
cache_mode = "USE_ORIGIN_HEADERS"
signed_url_cache_max_age_sec = 0
negative_caching = true
negative_caching_policy {
code = 404
ttl = 60
}
negative_caching_policy {
code = 502
ttl = 10
}
}
backend {
group = google_compute_region_network_endpoint_group.cloud_run.id
}
log_config {
enable = true
sample_rate = 0.5
}
}
# HTTPS プロキシ
resource "google_compute_target_https_proxy" "cdn" {
name = "${var.project}-cdn-https-proxy"
url_map = google_compute_url_map.cdn.id
ssl_certificates = [google_compute_managed_ssl_certificate.cdn_cert.id]
}
# フォワーディングルール
resource "google_compute_global_forwarding_rule" "cdn" {
name = "${var.project}-cdn-forwarding"
target = google_compute_target_https_proxy.cdn.id
port_range = "443"
ip_address = google_compute_global_address.cdn_ip.address
}
Cloud Runとの連携は「Google Cloud Cloud Run AutoScalingガイド」を参照してください。
SES案件でのCDNスキルの市場価値
| スキルレベル | 想定月額単価 | 求められるスキル |
|---|---|---|
| 基本 | 60〜75万円 | CDNの基本設定・Cache-Control設計 |
| 中級 | 75〜90万円 | キャッシュキー最適化・監視設計 |
| 上級 | 90〜110万円 | マルチオリジン設計・セキュリティ統合 |
| エキスパート | 110万円〜 | グローバルCDNアーキテクチャ設計 |
ロードバランシングの基礎は「Google Cloud Load Balancingガイド」を参照してください。
まとめ:Cloud CDNでWebパフォーマンスを最大化
この記事のポイントをまとめます。
- Cloud CDNはGoogle Load Balancingと統合された高性能CDNで、200以上のエッジPoPからコンテンツを配信
- Cache-Controlヘッダーの適切な設計がキャッシュヒット率向上の鍵
- キャッシュキーの最適化でトラッキングパラメータ等による不要なキャッシュ分割を防止
- Cloud Armorとの連携でCDNレイヤーでのDDoS防御・WAF保護を実現
- Signed URL/Cookieで認証付きコンテンツの安全な配信が可能
- TerraformでCDN・ロードバランサー・セキュリティポリシーを一括管理
Cloud CDNスキルを身につけ、Webパフォーマンス最適化案件での市場価値を高めましょう。
SES BASEでインフラ・パフォーマンス案件を探す
CDN・クラウドインフラ・パフォーマンス最適化の経験を活かせるSES案件をSES BASEで検索してみてください。