𝕏 f B! L
案件・求人数 12,345
案件を探す(準備中) エージェントを探す(準備中) お役立ち情報 ログイン
案件・求人数 12,345
Google Cloud Memorystore for Redis完全ガイド|キャッシュ設計・セッション管理・高可用性構成【SES案件対応】

Google Cloud Memorystore for Redis完全ガイド|キャッシュ設計・セッション管理・高可用性構成【SES案件対応】

Google CloudMemorystoreRedisキャッシュSES
目次

「アプリケーションのレスポンスが遅くてDBに負荷が集中している」「セッション管理をインメモリで高速化したい」「Redisの運用・監視を楽にしたい」——バックエンド開発でキャッシュ層の導入は避けて通れない課題です。

結論から言えば、Google Cloud Memorystore for Redisはフルマネージドのインメモリデータストアとして、キャッシュ・セッション管理・Pub/Subの基盤を簡単に構築できます。本記事では、基本概念から本番運用のベストプラクティスまで解説します。

この記事を3秒でまとめると

  • MemorystoreはRedis互換のフルマネージドサービスで、パッチ適用・フェイルオーバーが自動
  • キャッシュアサイド・ライトスルー・セッションストアなど実践的な設計パターンを解説
  • Cloud Run / GKEとのVPC接続でマイクロサービスからの高速アクセスが可能

Google Cloud Memorystore for Redisの全体像

Memorystore for Redisとは

Memorystore for Redisは、Google Cloudが提供するフルマネージドのRedisサービスです。Redisのインストール・パッチ適用・レプリケーション・フェイルオーバーをすべてGoogleが管理するため、エンジニアはアプリケーション開発に集中できます。

Memorystore vs セルフマネージドRedis

比較項目MemorystoreセルフマネージドRedis
セットアップ数クリック / コマンド一つVM構築、インストール、設定
パッチ適用自動手動
レプリケーションStandard Tier で自動手動設定
フェイルオーバー自動(サブ秒)手動 or Sentinel設定
監視Cloud Monitoring統合Prometheus等を自前構築
バックアップRDB/AOF自動手動設定
料金メモリ量に応じた従量課金VM料金 + 運用コスト

Memorystore のティア

ティア特徴用途
Basicシングルノード、SLA なし開発・テスト環境
Standardリードレプリカ + 自動フェイルオーバー本番環境

インスタンスの作成

gcloud CLIでの作成

# Standard Tier(本番推奨)
gcloud redis instances create ses-cache \
  --size=2 \
  --region=asia-northeast1 \
  --zone=asia-northeast1-a \
  --alternative-zone=asia-northeast1-c \
  --tier=standard \
  --redis-version=redis_7_2 \
  --network=projects/ses-base-prod/global/networks/ses-vpc \
  --connect-mode=PRIVATE_SERVICE_ACCESS \
  --enable-auth \
  --transit-encryption-mode=SERVER_AUTHENTICATION \
  --maintenance-window-day=SUNDAY \
  --maintenance-window-hour=3 \
  --labels=project=ses-base,environment=production

Terraformでの定義

# memorystore.tf
resource "google_redis_instance" "ses_cache" {
  name           = "ses-cache"
  tier           = "STANDARD_HA"
  memory_size_gb = 2
  region         = "asia-northeast1"

  location_id             = "asia-northeast1-a"
  alternative_location_id = "asia-northeast1-c"

  redis_version = "REDIS_7_2"

  authorized_network = google_compute_network.ses_vpc.id
  connect_mode       = "PRIVATE_SERVICE_ACCESS"

  auth_enabled             = true
  transit_encryption_mode  = "SERVER_AUTHENTICATION"

  redis_configs = {
    "maxmemory-policy" = "allkeys-lru"
    "notify-keyspace-events" = "Ex"
    "activedefrag"     = "yes"
  }

  maintenance_policy {
    weekly_maintenance_window {
      day = "SUNDAY"
      start_time {
        hours   = 3
        minutes = 0
      }
    }
  }

  labels = {
    project     = "ses-base"
    environment = "production"
  }

  depends_on = [google_service_networking_connection.private_vpc]
}

output "redis_host" {
  value = google_redis_instance.ses_cache.host
}

output "redis_port" {
  value = google_redis_instance.ses_cache.port
}

キャッシュ設計パターン

パターン1: キャッシュアサイド(Cache-Aside)

最も一般的なキャッシュパターンです。アプリケーションがキャッシュとデータベースの両方を管理します。

// services/cache.service.ts
import Redis from 'ioredis';

const redis = new Redis({
  host: process.env.REDIS_HOST,
  port: parseInt(process.env.REDIS_PORT || '6379'),
  password: process.env.REDIS_AUTH_STRING,
  tls: { rejectUnauthorized: false },
  retryDelayOnFailover: 100,
  maxRetriesPerRequest: 3,
});

// Cache-Aside パターン
export async function getWithCache<T>(
  key: string,
  fetcher: () => Promise<T>,
  ttlSeconds: number = 3600
): Promise<T> {
  // 1. キャッシュを確認
  const cached = await redis.get(key);
  if (cached) {
    return JSON.parse(cached) as T;
  }

  // 2. キャッシュミス → DBから取得
  const data = await fetcher();

  // 3. キャッシュに保存
  await redis.setex(key, ttlSeconds, JSON.stringify(data));

  return data;
}

// 使用例
export async function getUserProfile(userId: string) {
  return getWithCache(
    `user:profile:${userId}`,
    () => db.users.findUnique({ where: { id: userId } }),
    1800 // 30分キャッシュ
  );
}

パターン2: ライトスルー(Write-Through)

書き込み時にキャッシュとデータベースを同時に更新します。データの一貫性が重要な場合に適しています。

// Write-Through パターン
export async function updateUserProfile(
  userId: string,
  data: Partial<UserProfile>
): Promise<UserProfile> {
  // 1. DBを更新
  const updated = await db.users.update({
    where: { id: userId },
    data,
  });

  // 2. キャッシュも同時に更新
  const cacheKey = `user:profile:${userId}`;
  await redis.setex(cacheKey, 1800, JSON.stringify(updated));

  return updated;
}

パターン3: キャッシュ無効化(Cache Invalidation)

データ更新時にキャッシュを削除し、次のアクセス時に再取得させます。

// Cache Invalidation パターン
export async function invalidateCache(pattern: string): Promise<number> {
  const keys = await redis.keys(pattern);
  if (keys.length === 0) return 0;

  const pipeline = redis.pipeline();
  keys.forEach((key) => pipeline.del(key));
  await pipeline.exec();

  return keys.length;
}

// 使用例:ユーザー関連のキャッシュを一括無効化
await invalidateCache('user:*:123');

セッション管理

Express + connect-redisによるセッションストア

// session.config.ts
import session from 'express-session';
import RedisStore from 'connect-redis';
import Redis from 'ioredis';

const redisClient = new Redis({
  host: process.env.REDIS_HOST,
  port: parseInt(process.env.REDIS_PORT || '6379'),
  password: process.env.REDIS_AUTH_STRING,
  tls: { rejectUnauthorized: false },
  keyPrefix: 'sess:',
});

const store = new RedisStore({
  client: redisClient,
  prefix: 'sess:',
  ttl: 86400, // 24時間
  disableTouch: false,
});

export const sessionMiddleware = session({
  store,
  secret: process.env.SESSION_SECRET!,
  resave: false,
  saveUninitialized: false,
  name: 'ses.sid',
  cookie: {
    secure: process.env.NODE_ENV === 'production',
    httpOnly: true,
    maxAge: 24 * 60 * 60 * 1000, // 24時間
    sameSite: 'lax',
    domain: '.ses-base.com',
  },
});

セッション管理のベストプラクティス

項目推奨設定理由
TTL24時間セッション固定攻撃の防止
Cookie属性httpOnly, secure, sameSiteXSS/CSRF対策
プレフィックスsess:キャッシュデータとの分離
シリアライズJSONデバッグの容易さ

Cloud Run / GKEとの接続

Cloud RunからMemorystoreへの接続

Cloud RunからMemorystoreにアクセスするには、VPCコネクタまたはDirect VPC Egressを設定します。

# VPCコネクタの作成
gcloud compute networks vpc-access connectors create ses-connector \
  --region=asia-northeast1 \
  --network=ses-vpc \
  --range=10.8.0.0/28 \
  --min-instances=2 \
  --max-instances=10

# Cloud RunサービスにVPCコネクタを設定
gcloud run deploy ses-api \
  --image=asia-northeast1-docker.pkg.dev/ses-base-prod/ses-repo/api-server:latest \
  --region=asia-northeast1 \
  --vpc-connector=ses-connector \
  --vpc-egress=private-ranges-only \
  --set-env-vars="REDIS_HOST=$(gcloud redis instances describe ses-cache --region=asia-northeast1 --format='value(host)')"

Direct VPC Egress(推奨)

VPCコネクタの代わりにDirect VPC Egressを使うと、追加のインフラなしでVPC内のリソースにアクセスできます。

gcloud run deploy ses-api \
  --image=asia-northeast1-docker.pkg.dev/ses-base-prod/ses-repo/api-server:latest \
  --region=asia-northeast1 \
  --network=ses-vpc \
  --subnet=ses-private-subnet \
  --vpc-egress=private-ranges-only

監視とアラート

Cloud Monitoringダッシュボード

Memorystoreは Cloud Monitoring と自動統合されています。以下のメトリクスを監視します。

メトリクス警告閾値緊急閾値対処法
redis.googleapis.com/stats/memory/usage_ratio70%85%インスタンスのスケールアップ or データ整理
redis.googleapis.com/stats/cpu_utilization60%80%コマンド最適化 or スケールアップ
redis.googleapis.com/stats/connected_clients接続数の80%接続数の90%コネクションプール設定の見直し
redis.googleapis.com/stats/cache_hit_ratio80%以下60%以下TTL / キャッシュ戦略の見直し
redis.googleapis.com/stats/evicted_keys0超過急増メモリ増設 or ポリシー見直し

アラートポリシーの設定

# メモリ使用率85%超過でアラート
gcloud monitoring policies create \
  --display-name="Memorystore Memory Critical" \
  --condition-display-name="Redis memory usage > 85%" \
  --condition-filter='resource.type="redis_instance" AND metric.type="redis.googleapis.com/stats/memory/usage_ratio"' \
  --condition-threshold-value=0.85 \
  --condition-threshold-comparison=COMPARISON_GT \
  --condition-threshold-duration=300s \
  --notification-channels=projects/ses-base-prod/notificationChannels/12345

パフォーマンス最適化

1. パイプラインの活用

複数のコマンドをまとめて送信することで、ネットワークラウンドトリップを削減します。

// パイプラインなし(遅い)
for (const key of keys) {
  await redis.get(key); // 各コマンドでラウンドトリップ発生
}

// パイプラインあり(速い)
const pipeline = redis.pipeline();
keys.forEach((key) => pipeline.get(key));
const results = await pipeline.exec();

2. Lua スクリプトによるアトミック操作

// レート制限(スライディングウィンドウ方式)
const rateLimitScript = `
  local key = KEYS[1]
  local limit = tonumber(ARGV[1])
  local window = tonumber(ARGV[2])
  local now = tonumber(ARGV[3])

  redis.call('ZREMRANGEBYSCORE', key, 0, now - window)
  local count = redis.call('ZCARD', key)

  if count < limit then
    redis.call('ZADD', key, now, now .. '-' .. math.random())
    redis.call('EXPIRE', key, window / 1000)
    return 1
  else
    return 0
  end
`;

export async function checkRateLimit(
  userId: string,
  limit: number = 100,
  windowMs: number = 60000
): Promise<boolean> {
  const result = await redis.eval(
    rateLimitScript,
    1,
    `rate_limit:${userId}`,
    limit,
    windowMs,
    Date.now()
  );
  return result === 1;
}

3. コネクションプールの適切な設定

const redis = new Redis({
  host: process.env.REDIS_HOST,
  port: 6379,
  password: process.env.REDIS_AUTH_STRING,
  tls: { rejectUnauthorized: false },

  // コネクション管理
  lazyConnect: true,
  maxRetriesPerRequest: 3,
  retryDelayOnFailover: 100,
  enableReadyCheck: true,

  // タイムアウト
  connectTimeout: 10000,
  commandTimeout: 5000,

  // 再接続戦略
  retryStrategy(times) {
    const delay = Math.min(times * 50, 2000);
    return delay;
  },
});

コスト最適化

Memorystoreの料金体系

メモリサイズBasic Tier(月額)Standard Tier(月額)
1 GB約 $35約 $70
2 GB約 $70約 $140
5 GB約 $175約 $350
10 GB約 $350約 $700

コスト削減のTips

  1. 適切なTTL設定: 不要なデータの蓄積を防止
  2. 圧縮: 大きなJSONデータはlz4等で圧縮してから保存
  3. データ型の使い分け: HashでフィールドごとにTTLを管理する代わりに、Stringで適切にキーを分割
  4. Basic Tierの活用: 開発・テスト環境ではBasic Tierを使用

SES案件でのRedis/キャッシュスキル需要

スキルレベル要求される技術想定月額単価
初級Redis基本操作、キャッシュ設定50〜60万円
中級キャッシュ設計パターン、セッション管理60〜80万円
上級分散キャッシュ設計、パフォーマンスチューニング80〜100万円

まとめ:Memorystoreでキャッシュ基盤を構築しよう

Google Cloud Memorystore for Redisは、アプリケーションのパフォーマンスを劇的に向上させるフルマネージドサービスです。キャッシュアサイド・ライトスルーなどの設計パターンを適切に適用し、Cloud RunやGKEと連携することで、高速かつスケーラブルなバックエンドを構築できます。

SESエンジニアとして、キャッシュ設計のスキルはバックエンド案件での必須能力です。Memorystoreを使いこなして、高パフォーマンスなシステム設計力を身につけましょう。

Google Cloudの基本はGoogle Cloud入門ガイドを、Cloud RunについてはCloud Run + Cloud SQLチュートリアルをご覧ください。データベースはCloud SQL最適化ガイド、セキュリティはIAMセキュリティが参考になります。

SES案件をお探しですか?

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

SES BASE 編集長

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

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