𝕏 f B! L
案件・求人数 12,345
案件を探す(準備中) エージェントを探す(準備中) お役立ち情報 ログイン
案件・求人数 12,345
Google Cloud CDN パフォーマンス最適化ガイド|キャッシュ設計からコスト削減までSESエンジニア向けに解説

Google Cloud CDN パフォーマンス最適化ガイド|キャッシュ設計からコスト削減までSESエンジニア向けに解説

Google CloudCloud CDNパフォーマンス最適化キャッシュコンテンツ配信
目次
⚡ 3秒でわかる!この記事のポイント
  • 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 CDNCloudFrontCloudflare
エッジPOP数200+600+310+
HTTP/3対応
WebSocket対応
WAF統合Cloud ArmorAWS 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-agestale-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 + "%") }
'

Google Cloud CDN パフォーマンス最適化の構成図解

認証付きコンテンツ配信

プレミアムコンテンツや認証が必要なアセットの配信には、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リクエスト

コスト削減のベストプラクティス

  1. キャッシュヒット率を最大化:Cache-Controlヘッダーとキャッシュキーの最適化
  2. 圧縮の有効化:Brotli/gzip圧縮で転送量を削減
  3. 画像の最適化:WebP/AVIFフォーマットの活用
  4. 不要なバリエーションを削除:キャッシュキーから不要なパラメータを除外
# 圧縮設定
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で検索してみてください。

SES案件をお探しですか?

SES記事をもっと読む →
🏗️

SES BASE 編集長

SES業界歴10年以上のメンバーが在籍する編集チーム。SES企業での営業・エンジニア経験、フリーランス独立経験を持つメンバーが、業界のリアルな情報をお届けします。

📊 業界データに基づく記事制作 🔍 IPA・経済産業省データ参照 💼 SES実務経験者が執筆・監修