Memorystore for Redisを用いてセッション管理を行う

Memorystore for Redisを用いてセッション管理を行う

Google CloudのCloud RunとMemorystore for Redisを使用したセッション管理を行ってみました。
2026.08.10

はじめに

こんにちは。
クラウド事業本部コンサルティング部の渡邉です。

Webアプリケーションを運用する際に、「セッション管理」について考える場面があると思います。特に Cloud Run のようなサーバーレス環境では、インスタンスがスケールイン/アウトするため、ローカルメモリにセッションを保持する方式では正しくセッション管理を行えません。

そこで今回は、Google Cloud のフルマネージドなインメモリデータストアである Memorystore for Redis を使い、Cloud Run 上の Web アプリケーションでセッション管理を行う方法について紹介します。

セッション管理とは

改めて、Webアプリケーションにおける セッション管理 とは、ユーザーごとの一時的な状態(ログイン状態、カートの中身、フォームの入力途中データなど)をサーバー側で保持する仕組みです。

HTTP はステートレスなプロトコルであるため、リクエスト間で状態を保持するにはセッション管理の仕組みが必要です。一般的には、以下のような流れで動作します。

セッションストアの選択肢

セッションデータの保存先としては、いくつかの選択肢があります。

保存先 メリット デメリット
アプリのローカルメモリ 最もシンプル スケールアウト時にセッションが失われる
データベース(Cloud SQL など) 永続性が高い レイテンシが大きい
インメモリストア(Redis など) 低レイテンシ・高スループット データの永続性に注意が必要

Cloud Run のようにインスタンスが動的にスケールする環境では、外部のセッションストアを使うことが推奨されます。中でも Redis は、サブミリ秒のレイテンシとキーの有効期限(TTL)機能を備えており、セッション管理に適したデータストアとして知られています。

Memorystore for Redis とは

Memorystore for Redis は、Google Cloud が提供する Redis のフルマネージドサービスです。Redis のプロトコルに完全互換で、既存の Redis クライアントライブラリをそのまま利用できます。

主な特徴は以下のとおりです。

項目 内容
マネージド パッチ適用、障害検知、自動フェイルオーバーを自動化
サービスティア Basic Tier(単一ノード)/ Standard Tier(レプリケーション・自動フェイルオーバー)
最大容量 300 GB
ネットワーク帯域 最大 16 Gbps
サポートバージョン Redis 7.2, 7.0, 6.x
セキュリティ プライベート IP でのアクセス、IAM によるアクセス制御、転送中の暗号化
監視 Cloud Monitoring / Cloud Logging と統合
課金 プロビジョニングした容量(GB)に対する時間課金

Memorystore for Redisを構築・運用する上で、サービスティアについて理解することが大切になります。Basic Tier はレプリケーションのないスタンドアロン構成です。キャッシュ用途で一時的なデータを扱う場合に適しています。Standard Tier はゾーン間レプリケーションと自動フェイルオーバーを備え、99.9% の SLA を提供します。セッション管理で高可用性が必要な場合は Standard Tier を検討してください。

Cloud Run から Memorystore に接続するアーキテクチャ

Cloud Run から Memorystore for Redis に接続するには、VPC ネットワーク経由でのアクセスが必要です。Memorystore for Redis はプライベート IP のみで公開されるため、Cloud Run サービスが同じ VPC ネットワークにアクセスできる必要があります。

接続方式として Direct VPC egress が推奨されています。Direct VPC egress は、Serverless VPC Access コネクタを使う方式と比較して、低レイテンシ・高スループット・低コストというメリットがあります。Direct VPC egress を使用する場合、サブネットは /26 以上のサイズが必要になることに注意が必要です。本記事では /24 を使用しています。

実際に試してみる

ここからは、Cloud Run 上の Python(Flask)アプリケーションから Memorystore for Redis に接続し、セッション管理を行う手順を紹介します。

前提条件

  • Google Cloud プロジェクトが作成済みであること
  • gcloud CLI がインストール・認証済みであること
  • 以下の API が有効化されていること
    • Redis API(redis.googleapis.com
    • Cloud Run API(run.googleapis.com
    • Artifact Registry API(artifactregistry.googleapis.com
    • Cloud Build API(cloudbuild.googleapis.com
    • Compute Engine API(compute.googleapis.com

環境変数の設定

以降のコマンドで使用する変数を設定します。

export PROJECT_ID=YOUR_PROJECT_ID
export REGION=asia-northeast1
export NETWORK=session-network
export SUBNET=session-subnet

gcloud config set project $PROJECT_ID

ステップ 1: API の有効化

今回の検証で必要な各種サービスに対するAPIを有効化します。

gcloud services enable \
  redis.googleapis.com \
  run.googleapis.com \
  artifactregistry.googleapis.com \
  cloudbuild.googleapis.com \
  compute.googleapis.com \
  --project=$PROJECT_ID

Operation "operations/acf.p2-XXXXXXXXXXXX-a7e2db03-f800-4f7a-bec2-547b7ea53a74" finished successfully.

ステップ 2: VPC ネットワークとサブネットの作成

Memorystore for Redis はプライベート IP でのみアクセス可能なため、専用の VPC ネットワークとサブネットを作成します。

# VPC ネットワークの作成(カスタムモード)
gcloud compute networks create $NETWORK \
  --subnet-mode=custom \
  --project=$PROJECT_ID

# サブネットの作成
gcloud compute networks subnets create $SUBNET \
  --network=$NETWORK \
  --region=$REGION \
  --range=10.0.0.0/24 \
  --project=$PROJECT_ID

Created [https://www.googleapis.com/compute/v1/projects/YOUR_PROJECT_ID/global/networks/session-network].
NAME             SUBNET_MODE  BGP_ROUTING_MODE  IPV4_RANGE  GATEWAY_IPV4  INTERNAL_IPV6_RANGE
session-network  CUSTOM       REGIONAL

Created [https://www.googleapis.com/compute/v1/projects/YOUR_PROJECT_ID/regions/asia-northeast1/subnetworks/session-subnet].
NAME            REGION           NETWORK          RANGE        STACK_TYPE  IPV6_ACCESS_TYPE  INTERNAL_IPV6_PREFIX  EXTERNAL_IPV6_PREFIX
session-subnet  asia-northeast1  session-network  10.0.0.0/24  IPV4_ONLY

Google Cloud コンソールで作成された session-network VPC とサブネット session-subnet(10.0.0.0/24)の詳細画面
構築したVPCとサブネット

ステップ 3: Memorystore for Redis インスタンスの作成

検証用に Basic Tier で 1 GB のインスタンスを作成します。--network で作成した VPC ネットワークを指定し、接続モードには DIRECT_PEERING を使用します。

gcloud redis instances create session-store \
  --size=1 \
  --region=$REGION \
  --zone=asia-northeast1-a \
  --network=$NETWORK \
  --connect-mode=DIRECT_PEERING \
  --redis-version=redis_7_2 \
  --project=$PROJECT_ID

作成が完了したら、IP アドレスとポート番号を確認します。

gcloud redis instances describe session-store \
  --region=$REGION \
  --project=$PROJECT_ID \
  --format="value(host,port)"

10.255.217.203  6379

Memorystore コンソールに表示された session-store インスタンス(Basic、Redis 7.2、asia-northeast1)

ステップ 4: サンプルアプリケーションの作成

セッション管理を行う Flask アプリケーションを作成します。redis-pyFlask を使い、Redis をセッションストアとして利用します。

requirements.txt

Flask==3.1.3
gunicorn==23.0.0
redis==6.0.0

app.py

import os
import uuid
import json
from datetime import datetime

from flask import Flask, request, make_response
import redis

app = Flask(__name__)

redis_host = os.environ.get("REDISHOST", "localhost")
redis_port = int(os.environ.get("REDISPORT", 6379))
redis_client = redis.StrictRedis(host=redis_host, port=redis_port, decode_responses=True)

SESSION_TTL = 3600  # セッションの有効期限: 1時間

def get_or_create_session(session_id):
    """既存のセッションを取得、または新規作成する"""
    if session_id:
        session_data = redis_client.get(f"session:{session_id}")
        if session_data:
            redis_client.expire(f"session:{session_id}", SESSION_TTL)
            return session_id, json.loads(session_data)

    new_session_id = str(uuid.uuid4())
    session_data = {"created_at": datetime.now().isoformat(), "visit_count": 0}
    redis_client.setex(f"session:{new_session_id}", SESSION_TTL, json.dumps(session_data))
    return new_session_id, session_data

@app.route("/")
def index():
    session_id = request.cookies.get("session_id")
    session_id, session_data = get_or_create_session(session_id)

    session_data["visit_count"] += 1
    session_data["last_visited"] = datetime.now().isoformat()
    redis_client.setex(f"session:{session_id}", SESSION_TTL, json.dumps(session_data))

    response = make_response(
        f"Session ID: {session_id}\n"
        f"Visit Count: {session_data['visit_count']}\n"
        f"Created At: {session_data['created_at']}\n"
        f"Last Visited: {session_data['last_visited']}\n"
    )
    response.set_cookie("session_id", session_id, max_age=SESSION_TTL, httponly=True)
    return response

@app.route("/session/delete")
def delete_session():
    session_id = request.cookies.get("session_id")
    if session_id:
        redis_client.delete(f"session:{session_id}")

    response = make_response("Session deleted.\n")
    response.delete_cookie("session_id")
    return response

if __name__ == "__main__":
    app.run(host="0.0.0.0", port=8080, debug=True)

このアプリケーションでは以下のポイントを実装しています。

  • GET /: セッションの作成・更新。訪問回数をカウントする
  • GET /session/delete: セッションの削除
  • setex コマンドで TTL(有効期限)を設定し、一定期間アクセスがないセッションを自動削除
  • アクセスのたびに expire で TTL をリセットし、アクティブなセッションを延長

Dockerfile

FROM python:3.12-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY app.py .
CMD ["gunicorn", "--bind", "0.0.0.0:8080", "app:app"]

ステップ 5: コンテナイメージのビルドとプッシュ

Artifact Registry にリポジトリを作成し、Cloud Build でコンテナイメージをビルドします。

# Artifact Registry リポジトリの作成
gcloud artifacts repositories create session-app \
  --location=$REGION \
  --repository-format=docker \
  --project=$PROJECT_ID

Create request issued for: [session-app]
Waiting for operation [projects/YOUR_PROJECT_ID/locations/asia-northeast1/operations/f23a24b5-d298-487c-94d0-38e5806ea8bc] to complete...done.
Created repository [session-app].

# Cloud Build でイメージをビルド
gcloud builds submit \
  --pack image=$REGION-docker.pkg.dev/$PROJECT_ID/session-app/session-app:v1 \
  --project=$PROJECT_ID

DONE
-------------------------------------------------------------------------------------------------------------------------------------
ID                                    CREATE_TIME                DURATION  SOURCE                                                                                               IMAGES                                                                           STATUS
d4318002-04d6-4deb-b0aa-afc7a8ede6bc  2026-08-09T19:59:21+00:00  1M33S     gs://YOUR_PROJECT_ID_cloudbuild/source/1786305557.062782-def279db5f6a4195bb3069489e3c126e.tgz  asia-northeast1-docker.pkg.dev/YOUR_PROJECT_ID/session-app/session-app:v1  SUCCESS

Artifact Registry の session-app リポジトリに v1 タグ付きのコンテナイメージが格納されている画面

ステップ 6: Cloud Run へのデプロイ

Memorystore の IP アドレスを取得し、Cloud Run サービスをデプロイします。Direct VPC egress を使用して VPC ネットワークに接続します。

# Memorystore の IP アドレスを取得
REDIS_IP=$(gcloud redis instances describe session-store \
  --region=$REGION \
  --project=$PROJECT_ID \
  --format="value(host)")

REDIS_PORT=$(gcloud redis instances describe session-store \
  --region=$REGION \
  --project=$PROJECT_ID \
  --format="value(port)")

# Cloud Run へデプロイ
gcloud run deploy session-app \
  --image=$REGION-docker.pkg.dev/$PROJECT_ID/session-app/session-app:v1 \
  --region=$REGION \
  --network=$NETWORK \
  --subnet=$SUBNET \
  --vpc-egress=private-ranges-only \
  --set-env-vars=REDISHOST=$REDIS_IP,REDISPORT=$REDIS_PORT \
  --allow-unauthenticated \
  --project=$PROJECT_ID

Deploying container to Cloud Run service [session-app] in project [YOUR_PROJECT_ID] region [asia-northeast1]
 Deploying new service... Done.                                                                                                    
 Creating Revision...                                                                                                            
 Routing traffic...                                                                                                              
 Setting IAM Policy...                                                                                                           
Done.                                                                                                                               
Service [session-app] revision [session-app-00001-5qh] has been deployed and is serving 100 percent of traffic.
Service URL: https://session-app-XXXXXXXXXXXX.asia-northeast1.run.app

Cloud Run コンソールに表示された session-app サービス(asia-northeast1、Public access)

ステップ 7: 動作確認

デプロイされた Cloud Run サービスの URL を取得し、動作を確認します。

# サービス URL の取得
SERVICE_URL=$(gcloud run services describe session-app \
  --region=$REGION \
  --project=$PROJECT_ID \
  --format="value(status.url)")

$ curl -c cookies.txt $SERVICE_URL
Session ID: 49accccb-5450-4293-b8b0-beb9c1d09d6e
Visit Count: 1
Created At: 2026-08-09T20:03:45.781155
Last Visited: 2026-08-09T20:03:45.784427

$ curl -b cookies.txt -c cookies.txt $SERVICE_URL
Session ID: 49accccb-5450-4293-b8b0-beb9c1d09d6e
Visit Count: 2
Created At: 2026-08-09T20:03:45.781155
Last Visited: 2026-08-09T20:03:52.656581

$ curl -b cookies.txt -c cookies.txt $SERVICE_URL
Session ID: 49accccb-5450-4293-b8b0-beb9c1d09d6e
Visit Count: 3
Created At: 2026-08-09T20:03:45.781155
Last Visited: 2026-08-09T20:03:59.438163

$ curl -b cookies.txt -c cookies.txt $SERVICE_URL/session/delete
Session deleted.

1回目のアクセスでは Visit Count: 1 が返り、2回目以降はカウントが増加していくことが確認できます。

ブラウザからアクセスする場合、サーバーが Set-Cookie ヘッダーを返すと、ブラウザが自動的に Cookie を保存し、以降の同一ドメインへのリクエストに Cookie: session_id=xxx を付与します。開発者が明示的に Cookie を扱うコードを書く必要はありません。

一方、curl はブラウザではないため Cookie を自動管理しません。上記のコマンドでは -c cookies.txt(Cookie の保存)と -b cookies.txt(Cookie の送信)を明示的に指定することで、ブラウザと同等のセッション維持を再現しています。

以下のシーケンス図は、複数回アクセスした際のセッション管理の流れを示しています。

まとめ

本記事では、Memorystore for RedisCloud Run を使って Web アプリケーションのセッション管理を行う方法を紹介しました。

Memorystore for Redis は、セッション管理に最適なフルマネージドのインメモリデータストアです。サブミリ秒のレイテンシでデータにアクセスでき、Redis の TTL 機能を使うことで有効期限付きのセッション管理を簡潔に実装できます。パッチ適用や監視などの運用タスクが自動化されているため、アプリケーション開発に集中できる点も大きなメリットです。

Cloud Run から Memorystore への接続は、Direct VPC egress を使うことでシンプルに実現できます。従来の Serverless VPC Access コネクタと比較して、コネクタインスタンスが不要なため低コストであり、レイテンシやスループットの面でも優位です。なお、Memorystore for Redis はプライベート IP でのみアクセス可能なため、VPC ネットワークの設定は必須となります。

今回は検証用に Basic Tier を使用しましたが、本番環境では自動フェイルオーバーとゾーン間レプリケーションを備えた Standard Tier の利用を推奨します。セッションデータの喪失がユーザー体験に影響する場合は、Standard Tier により 99.9% の SLA が保証されるため、安心して運用できます。

この記事が誰かの助けになれば幸いです。

以上、クラウド事業本部コンサルティング部の渡邉でした!

この記事をシェアする

関連記事