発展LESSON 20
この教材で学ぶこと RDS・Aurora・DynamoDB・ElastiCacheを要件から選びます。AWS データベースサービス — RDS・Aurora・DynamoDB・ElastiCache
前提知識: データベースの基本。本教材ではクラウドDBの選択・設計・運用を扱います。
1. どれを選ぶか(意思決定ツリー)
トランザクション・複雑な結合が必要?
YES → RDS / Aurora(リレーショナル)
高可用性・大規模?
YES → Aurora(MySQL/PostgreSQL 互換)
NO → RDS(シンプルなワークロード)
NO → 超高速・無制限スケール・スキーマレス?
YES → DynamoDB(キー・バリュー / ドキュメント)
セッション・キャッシュ・リーダーボード?
→ ElastiCache(Redis / Memcached)
全文検索?
→ OpenSearch Service
2. RDS — 基本設計
# Multi-AZ(高可用性)の仕組み
Primary DB (ap-northeast-1a) ←→ Standby DB (ap-northeast-1c)
↑同期レプリケーション
フェイルオーバー時間: 60〜120秒
エンドポイントは変わらない(DNS が切り替わる)
# Read Replica(読み取りスケール)
Primary → Read Replica 1 (同リージョン)
→ Read Replica 2 (別リージョン / DR 用)
非同期レプリケーション → ラグが発生することがある
# 接続ポーリング(RDS Proxy 経由)
# Lambda から直接 RDS に接続すると接続数を使い果たす問題
# RDS Proxy がプーリングを担当
import os
import psycopg2
# Lambda からは RDS Proxy エンドポイントに接続
conn = psycopg2.connect(
host=os.environ["RDS_PROXY_ENDPOINT"],
database="myapp",
user="myapp_user",
password=os.environ["DB_PASSWORD"], # Secrets Manager から取得
connect_timeout=5
)
3. Aurora — RDS との違い
Aurora の特徴:
ストレージ: 自動拡張(最大128TB)、6コピー(3AZ × 2)
読み取り: 最大15台の Read Replica(Writer と共有ストレージ)
フェイルオーバー: 30秒以内(RDS は 60-120秒)
Aurora Serverless v2:
最小 0.5 ACU(Aurora Capacity Unit)から自動スケール
→ 開発環境・アクセスが不規則なワークロードに最適
→ コールドスタートに注意(数秒かかることがある)
コスト: RDS より高い(ただし Read Replica は共有ストレージなので追加コスト小)
4. DynamoDB — キー設計が全て
DynamoDB のアーキテクチャ:
テーブル = パーティション集合
パーティションキー(PK)でデータの置き場所(パーティション)が決まる
同じ PK を持つアイテムは同じパーティションに入る
→ PK が偏ると「ホットパーティション」になりスロットリング発生
パーティションキーの選び方:
❌ ステータス(active/inactive)→ 偏る
❌ 日付(2024-01)→ 偏る
✅ ユーザーID → 分散しやすい
✅ UUID → ランダムに分散
アクセスパターン駆動設計(DynamoDB はこれが全て)
import boto3
from boto3.dynamodb.conditions import Key, Attr
dynamodb = boto3.resource("dynamodb")
table = dynamodb.Table("Orders")
# 設計前に「どんな問い合わせをするか」を列挙する
# アクセスパターン例:
# 1. ユーザー XXX の注文一覧を取得(日時降順)
# 2. 注文 ID で1件取得
# 3. ユーザー XXX のステータス「shipped」の注文一覧
# テーブル設計:
# PK: USER#userId
# SK: ORDER#timestamp#orderId
# GSI: status-index (PK=status, SK=createdAt)
# 1. ユーザーの注文一覧
response = table.query(
KeyConditionExpression=Key("PK").eq("USER#user001") &
Key("SK").begins_with("ORDER#"),
ScanIndexForward=False # 降順
)
# 2. 注文 ID で取得
response = table.get_item(
Key={"PK": "USER#user001", "SK": "ORDER#2024-01-15T10:00:00#order001"}
)
# 3. ステータスでフィルタ(GSI 使用)
response = table.query(
IndexName="status-index",
KeyConditionExpression=Key("status").eq("shipped") &
Key("createdAt").begins_with("2024-01")
)
5. DynamoDB — 本番設計のポイント
# トランザクション(2テーブルをまとめて更新)
dynamodb.meta.client.transact_write(
TransactItems=[
{
"Update": {
"TableName": "Orders",
"Key": {"PK": "ORDER#001"},
"UpdateExpression": "SET #status = :status",
"ExpressionAttributeNames": {"#status": "status"},
"ExpressionAttributeValues": {":status": "shipped"}
}
},
{
"Update": {
"TableName": "Inventory",
"Key": {"PK": "PRODUCT#001"},
"UpdateExpression": "SET stock = stock - :qty",
"ConditionExpression": "stock >= :qty", # 在庫チェック
"ExpressionAttributeValues": {":qty": 1}
}
}
]
)
# DynamoDB Streams → Lambda でのイベント駆動
# テーブルの変更をリアルタイムにキャプチャ → Lambda で処理
# 用途: 集計テーブル更新・Elasticsearch 同期・監査ログ
6. ElastiCache Redis — キャッシュパターン
import redis
import json
import hashlib
r = redis.Redis(host=os.environ["REDIS_HOST"], port=6379, decode_responses=True)
# Cache-Aside パターン(最も一般的)
def get_user(user_id: str) -> dict:
cache_key = f"user:{user_id}"
# 1. キャッシュから取得
cached = r.get(cache_key)
if cached:
return json.loads(cached)
# 2. DB から取得
user = db.query("SELECT * FROM users WHERE id = %s", user_id)
# 3. キャッシュに書き込み(TTL: 300秒)
r.setex(cache_key, 300, json.dumps(user))
return user
# セッション管理
def create_session(user_id: str, token: str) -> None:
r.setex(f"session:{token}", 3600, user_id)
def get_session(token: str) -> str | None:
return r.get(f"session:{token}")
# レート制限(スライディングウィンドウ)
def check_rate_limit(user_id: str, limit: int = 100) -> bool:
key = f"rate:{user_id}:{int(time.time()) // 60}"
count = r.incr(key)
if count == 1:
r.expire(key, 120)
return count <= limit
7. コスト最適化まとめ
RDS/Aurora:
✅ Reserved Instances(1年・3年契約)で最大60%削減
✅ 開発環境は Aurora Serverless v2(使わない時間は課金なし)
✅ Storage Autoscaling ON(過剰プロビジョニングを避ける)
DynamoDB:
✅ オンデマンド vs プロビジョニング済みの選択
→ アクセス予測可能 → プロビジョニング済み(安い)
→ 予測不能・スパイク → オンデマンド(安全)
✅ DynamoDB Standard-IA → アクセス頻度が低いデータを自動移行
ElastiCache:
✅ Reserved Nodes で最大55%削減
✅ キャッシュヒット率を CloudWatch で監視(低い → キャッシュ設計を見直す)
🔗 次のステップ
- ../../07_Databases/01_SQL実践_応用情報対策.md — SQL クエリ・正規化の基礎
- ../../07_Databases/02_RDB設計パターン.md — インデックス設計・クエリ最適化
- ../../07_Databases/03_NoSQL.md — DynamoDB 設計パターン詳細