08
第 8 章

ユースケースと
アーキテクチャパターン

この章で学ぶこと
1セッション管理における Redis の役割
2レートリミッティングの実装パターン
3リアルタイムランキングの設計
4分散ロックの仕組みと注意点
解説

セッション管理の課題

スティッキーセッション
同じユーザーを常に同じサーバーへ振り分ける方式
課題1
サーバー障害時にセッションが消失する
課題2
負荷が特定のサーバーに偏る
セッション管理
レートリミッティング
ランキング
分散ロック
まとめ
図解

セッションストア構成図

どのサーバーに振り分けても同じセッションデータにアクセスできる構成

セッション管理
レートリミッティング
ランキング
分散ロック
まとめ
コード

セッションストアのデータ設計

Hash + TTL によるセッション管理

redis-cli
キー設計: session:{セッションID}
データ構造: Hash

HSET session:abc123 user_id 42
HSET session:abc123 username "tanaka"
HSET session:abc123 role "admin"
EXPIRE session:abc123 1800
セッション管理
レートリミッティング
ランキング
分散ロック
まとめ
図解

実演環境 — セッション管理の構成

docker compose で立ち上げるコンテナとセッションの保存先

セッション管理
レートリミッティング
ランキング
分散ロック
まとめ
実演

セッション管理の実演

目的Redis をセッションストアとして使うアプリケーションの動作を確認する
操作docker compose up → curl でログイン → Redis でセッション確認 → サーバー停止 → 別サーバーでセッション維持を確認
確認する
ポイント
サーバー障害時にもセッションが維持されること
セッション管理
レートリミッティング
ランキング
分散ロック
まとめ
解説

レートリミッティングとは

レートリミッター
一定時間内のリクエスト数を制限する仕組み
目的
サーバーの過負荷を防ぐ・不正アクセスを抑止する
セッション管理
レートリミッティング
ランキング
分散ロック
まとめ
図解

固定ウィンドウカウンタの流れ

INCR でカウンタをインクリメントし、上限超過時にリクエストを拒否するフロー

セッション管理
レートリミッティング
ランキング
分散ロック
まとめ
コード

固定ウィンドウカウンタのコマンド

String(カウンタ)を使った固定ウィンドウの実装

redis-cli
キー設計: ratelimit:{ユーザーID}:{ウィンドウ}
データ構造: String(カウンタ)

INCR ratelimit:user42:2026-08-09T12:00
EXPIRE ratelimit:user42:2026-08-09T12:00 60

GET ratelimit:user42:2026-08-09T12:00
→ 上限(例: 100)を超えていれば拒否
セッション管理
レートリミッティング
ランキング
分散ロック
まとめ
図解

スライディングウィンドウの流れ

古いエントリを削除し、現在のリクエスト数を確認してから新しいエントリを追加するフロー

セッション管理
レートリミッティング
ランキング
分散ロック
まとめ
コード

スライディングウィンドウのコマンド

Sorted Set を使ったスライディングウィンドウの実装

redis-cli
キー設計: ratelimit:{ユーザーID}
データ構造: Sorted Set

ZREMRANGEBYSCORE ratelimit:user42 0 1786348740
ZCARD ratelimit:user42
→ 上限以下なら:
ZADD ratelimit:user42 1786348800 "req-uuid-xxx"
EXPIRE ratelimit:user42 60
セッション管理
レートリミッティング
ランキング
分散ロック
まとめ
図解

固定ウィンドウとスライディングウィンドウの比較

観点
固定ウィンドウ
スライディングウィンドウ
データ構造
String(カウンタ)
Sorted Set
精度
境界で突破される可能性あり
正確
メモリ使用量
少ない(キーあたり1値)
多い(リクエストごとにエントリ)
実装の複雑さ
シンプル
やや複雑
セッション管理
レートリミッティング
ランキング
分散ロック
まとめ
図解

実演環境 — レートリミッターの構成

リクエストがカウントされ、上限を超えると 429 が返るまでの経路

セッション管理
レートリミッティング
ランキング
分散ロック
まとめ
実演

レートリミッティングの実演

目的Redis を使ったレートリミッターの動作を確認する
操作docker compose up → API に連続リクエスト → 制限超過時の応答を確認 → Redis のデータを確認
確認する
ポイント
上限を超えるとリクエストが拒否されること
セッション管理
レートリミッティング
ランキング
分散ロック
まとめ
解説

リアルタイムランキングの設計

Sorted Set
スコア付きの順序集合。ランキングに最適なデータ構造
O(log N)
スコアの更新と順位の取得がともに対数時間で完了する
セッション管理
レートリミッティング
ランキング
分散ロック
まとめ
コード

ランキングの基本操作

Sorted Set によるランキングの登録と取得

redis-cli
ZADD ranking:game 1500 "player:alice"
ZADD ranking:game 2300 "player:bob"
ZADD ranking:game 1800 "player:carol"

ZREVRANGE ranking:game 0 2 WITHSCORES
→ 1) "player:bob"   2) "2300"
  3) "player:carol" 4) "1800"
  5) "player:alice" 6) "1500"

ZREVRANK ranking:game "player:carol"
→ 1  (0始まりで2位)
セッション管理
レートリミッティング
ランキング
分散ロック
まとめ
コード

スコアの更新

ZADD による上書きと ZINCRBY による加算

redis-cli
# スコアを上書き
ZADD ranking:game 2500 "player:alice"

# スコアを加算
ZINCRBY ranking:game 200 "player:carol"

# 更新後のランキング確認
ZREVRANGE ranking:game 0 2 WITHSCORES
セッション管理
レートリミッティング
ランキング
分散ロック
まとめ
図解

実演環境 — ランキングの構成

ranking API と Redis の Sorted Set によるランキング保持

GET /ranking
ZREVRANGE
スコアの高い順に取得(top で件数指定)
POST /ranking/score
ZADD
スコアを登録または上書き
POST /ranking/increment
ZINCRBY
スコアを加算
GET /ranking/player/{名前}
ZSCORE / ZREVRANK
個別プレイヤーのスコアと順位
セッション管理
レートリミッティング
ランキング
分散ロック
まとめ
実演

ランキングの実演

目的Sorted Set を使ったリアルタイムランキングの動作を確認する
操作docker compose up → スコア登録 → ランキング表示 → スコア更新 → ランキング再表示
確認する
ポイント
スコア更新後にランキングがリアルタイムに反映されること
セッション管理
レートリミッティング
ランキング
分散ロック
まとめ
解説

分散ロックとは

分散ロック
複数のプロセスやサーバーが、同じリソースに同時にアクセスすることを防ぐ仕組み
必要な場面
在庫の引き当て、決済処理、重複実行の防止
セッション管理
レートリミッティング
ランキング
分散ロック
まとめ
解説

なぜ Redis で分散ロックを実装するのか

高速
インメモリ処理でロックの取得・解放がミリ秒単位
TTL による自動解放
ロック保持者が異常終了しても、ロックが永久に残らない
原子的操作
SET NX EX で取得とタイムアウト設定を1コマンドで実行
セッション管理
レートリミッティング
ランキング
分散ロック
まとめ
コード

SET NX EX によるロックの取得

1コマンドで排他的なロック取得とタイムアウト設定を実行

redis-cli
# ロックの取得
SET lock:order:12345 "uuid-abc-123" NX EX 10

→ OK    … ロック取得成功
→ (nil) … 他のプロセスがロック済み
セッション管理
レートリミッティング
ランキング
分散ロック
まとめ
解説

ロックの所有者の識別

UUID を値にする理由
自分が取得したロックだけを解放するため
危険な操作
所有者を確認せず DEL すると他プロセスのロックを解放してしまう
セッション管理
レートリミッティング
ランキング
分散ロック
まとめ
コード

ロックの安全な解放

UUID を確認してから DEL で削除する手順

redis-cli
# 解放の手順(疑似コード)
1. GET lock:order:12345
2. 値が自分の UUID と一致するか確認
3. 一致すれば DEL lock:order:12345

# 注意: GET と DEL の間に他の操作が入る可能性がある
# → 本番では Lua スクリプトで原子的に実行する
セッション管理
レートリミッティング
ランキング
分散ロック
まとめ
図解

実演環境 — 分散ロックの構成

distributed-lock API と Redis によるロック状態の保持

POST /lock/acquire
SET NX EX
UUID を所有者 ID として取得(TTL 10 秒)/保持中なら 409
POST /lock/release
DEL
所有者 ID が一致する場合のみ解放/不一致は 403
GET /lock/status/{リソース名}
GET / TTL
ロックの有無・所有者・残り TTL を返す
セッション管理
レートリミッティング
ランキング
分散ロック
まとめ
実演

分散ロックの実演

目的SET NX EX による分散ロックの動作を確認する
操作docker compose up → 2つのプロセスから同時にロック取得を試行 → 一方が失敗することを確認 → TTL 自動解放の確認 → 所有者による解放と再取得
確認する
ポイント
同時に1つのプロセスだけがロックを保持できること・TTL でロックが自動解放されること
セッション管理
レートリミッティング
ランキング
分散ロック
まとめ
解説

分散ロックの限界

単一ノードの限界
Redis が停止するとロック情報が消失する
TTL の見積もりが困難
処理が TTL より長くかかると、ロックが途中で解放される
厳密な排他制御が必要な場合
ZooKeeper や etcd のような専用ツールを検討する
セッション管理
レートリミッティング
ランキング
分散ロック
まとめ
解説

セッション管理のまとめ

課題
スティッキーセッションの限界(障害・負荷偏り)
解決
Redis を共有セッションストアとして使用
データ設計
Hash + TTL(キー: session:{ID})
セッション管理
レートリミッティング
ランキング
分散ロック
まとめ
解説

レートリミッティングのまとめ

固定ウィンドウ
String(INCR + EXPIRE)。シンプルだが境界問題あり
スライディングウィンドウ
Sorted Set。正確だがメモリ使用量が多い
セッション管理
レートリミッティング
ランキング
分散ロック
まとめ
解説

ランキングと分散ロックのまとめ

ランキング
Sorted Set(ZADD / ZREVRANGE / ZINCRBY)。スコア更新で順位が自動反映
分散ロック
String(SET NX EX)。TTL で自動解放。UUID で所有者を識別
セッション管理
レートリミッティング
ランキング
分散ロック
まとめ
図解

ユースケースとデータ構造の対応

ユースケース
データ構造
主要コマンド
セッション管理
Hash
HSET / HGETALL / EXPIRE
レートリミッティング(固定)
String
INCR / EXPIRE
レートリミッティング(スライディング)
Sorted Set
ZADD / ZREMRANGEBYSCORE / ZCARD
ランキング
Sorted Set
ZADD / ZREVRANGE / ZINCRBY
分散ロック
String
SET NX EX / GET / DEL
セッション管理
レートリミッティング
ランキング
分散ロック
まとめ
まとめ

この章のまとめ

セッション管理: Hash + TTL で共有セッションストアを実現
レートリミッティング: 固定ウィンドウ(String)とスライディングウィンドウ(Sorted Set)
ランキング: Sorted Set でスコア更新と順位取得を高速に実現
分散ロック: SET NX EX + UUID で排他制御を実現
次章: レプリケーションと高可用性
セッション管理
レートリミッティング
ランキング
分散ロック
まとめ