Amazon MemoryDB

目次

初心者から実務者向けの包括的解説

Amazon MemoryDB for Valkey and Redis は、Redis/Valkey 互換のインメモリデータベース で、プライマリデータストアとして使用可能な永続性を提供します。マイクロ秒読み取り・シングル桁ミリ秒書き込みレイテンシを実現しながら、マルチ AZ トランザクションログで 99.99% 耐久性を保証。キャッシュではなく「メインの DB として Redis/Valkey を使いたい」というユースケースに最適。Valkey(Redis の オープンソースフォーク)を推奨・デフォルト化され、2026 年には Valkey ベースの新プロジェクトが標準になります。

このページの目的

このページでは以下を対象としています。

  • 初心者向け: MemoryDB とは何か、ElastiCache(キャッシュ)との違いを学びたい方
  • 開発者向け: Redis/Valkey ドライバー・データ構造の実装
  • データアーキテクト向け: インメモリプライマリ DB 設計・耐久性戦略
  • SRE/インフラ向け: マルチ AZ 構成・スケーリング・バックアップ
  • 意思決定者向け: ElastiCache vs MemoryDB、DynamoDB/RDS との比較・投資判断

2025-2026 年の MemoryDB エコシステム

  • Valkey デフォルト化(2024-2025): Redis から Valkey へのシフト加速、30% コスト削減(Valkey 優遇価格)
  • Vector Search対応: ベクトル埋め込み検索
  • JSON・Stream・Search データ型: Valkey 拡張で RedisJSON・RedisStream・RediSearch 対応
  • Auto Scaling 強化: より細かいスケーリング制御
  • Serverless オプション検討中:ElastiCache Serverless に倣った設計

概要

初心者向けメモ: MemoryDB は「Redis をデータベースとして使いたい」という要件に応える。Redis は高速だが「サーバー再起動でデータ消失」という制限があり、キャッシュレイヤーに適していた。MemoryDB は「Redis の速度 + DB の耐久性」を両立。インメモリなのでコストは高いが、「マイクロ秒の応答が必須」かつ「データ永続化も必須」なユースケースでは最適な選択肢。

MemoryDB は以下を実現します:

  • Redis/Valkey 完全互換:既存 Redis コード・ドライバーをそのまま使用可能
  • マイクロ秒読み取り:インメモリ処理で最低レイテンシ
  • シングル桁ミリ秒書き込み:トランザクションログ確認で耐久性確保
  • 99.99% 耐久性:マルチ AZ トランザクションログで 4 ナイン保証
  • 強整合性:書き込み確認後は全レプリカで同期

MemoryDB が解決する課題

課題 1: Redis の データ損失リスク

状況: ElastiCache Redis でゲームランキング・在庫管理を実装したが、ノード障害でデータ消失。再起動で 30 分のダウンタイム発生

ElastiCache の限界:

  • デフォルトで AOF(Append Only File)なし
  • ノード再起動 = メモリクリア
  • スナップショット は非同期(時間遅延あり)

MemoryDB の解決:

  • マルチ AZ トランザクションログで同期レプリケーション
  • ノード障害 < 10 秒で自動フェイルオーバー
  • 99.99% 耐久性保証
  • ゲームランキング・在庫の永続化

課題 2: キャッシュと DB の二重管理

状況: ElastiCache(キャッシュ)+ RDS(DB)を併用、データ同期が複雑・バグ誘発

従来設計:

  • アプリ → ElastiCache
  • → キャッシュミス → RDS
  • → キャッシュ更新

MemoryDB 設計:

アプリ → MemoryDB(プライマリ DB)
    └─ 永続化・耐久性保証
    └─ RDS 不要(インメモリ速度)

課題 3: 超低レイテンシーDB の要件

状況: ファイナンステック・オンラインゲームで「マイクロ秒応答」が必須だが、DynamoDB(ミリ秒)では不足

MemoryDB の解決:

  • 読み取り:マイクロ秒(インメモリ)
  • 書き込み:シングル桁ミリ秒(ログ確認で耐久性確保)
  • DynamoDB の 10~100 倍高速

主な特徴

graph TD
    A["MemoryDB クラスター<br/>インメモリ永続 DB"] --> B["Valkey / Redis<br/>完全互換"]
    A --> C["マルチ AZ<br/>トランザクションログ"]

    B --> D["データ構造<br/>String/List/Set/Hash/<br/>Sorted Set/Stream/JSON"]

    C --> E["Primary Node<br/>読み書き"]
    C --> F["Replica Nodes<br/>読み取り(最大 5)"]

    E --> G["マルチ AZ Log<br/>3 AZ レプリケーション"]

    H["永続性"] --> I["スナップショット<br/>手動・自動"]
    H --> J["トランザクション Log<br/>自動復旧"]

    K["スケーリング"] --> L["Auto Scaling<br/>トラフィック対応"]
    K --> M["シャーディング<br/>クラスター化"]

特徴の詳細

  1. Redis/Valkey API 互換

    • Redis の全データ構造をサポート
    • 既存 Redis ドライバー・コードをそのまま使用可能
    • Valkey(Redis フォーク)も完全互換
  2. インメモリパフォーマンス

    • 読み取り:マイクロ秒(< 1 ms)
    • 書き込み:シングル桁ミリ秒(ログ確認)
  3. マルチ AZ 耐久性

    • 3 AZ にトランザクションログレプリケーション
    • 99.99% SLA
    • < 10 秒フェイルオーバー
  4. 強整合性

    • 書き込み確認後、全レプリカで同期
    • ElastiCache(結果整合)と異なり

MemoryDB vs ElastiCache

ElastiCache(キャッシュ用途):
    アプリ → ElastiCache → キャッシュヒット
                        → キャッシュミス → DB(正規ストア)
    ↑ DB の前段キャッシュ。データ損失許容
    ↑ 目的:DB へのアクセス削減・レイテンシ改善

MemoryDB(プライマリ DB 用途):
    アプリ → MemoryDB(メインの DB として使用)
    ↑ DB そのもの。耐久性・整合性が必要
    ↑ 目的:超低レイテンシーと耐久性の両立
観点 ElastiCache MemoryDB
用途 キャッシュ(DB 前段) プライマリデータストア
耐久性 限定的(再起動で消失) 99.99%(マルチ AZ ログ)
整合性 結果整合(許容) 強整合性
レイテンシー マイクロ秒〜ミリ秒 マイクロ秒(読み取り)
コスト 高(永続性の対価)
Redis 互換
推奨用途 キャッシュ・セッション ゲーム・金融・在庫管理

MemoryDB vs DynamoDB/RDS

観点 MemoryDB DynamoDB RDS/Aurora
データモデル キーバリュー(Redis) キーバリュー・ドキュメント リレーショナル
レイテンシー マイクロ秒(読み) ミリ秒 ミリ秒〜
スケーリング 自動(ノード追加) 自動(ハーティション) 手動〜Auto Scaling
データ型 String/List/Set/Hash/Stream JSON 対応 SQL 標準型
複雑クエリ 限定的(Lua script) API 限定的 SQL の完全性
耐久性 99.99% 99.99% 99.95%
推奨用途 リアルタイムランキング・セッション モバイル・Web アプリ 複雑業務システム

Valkey vs Redis

Valkey とは?

Linux Foundation による Redis のオープンソースフォーク。Redis Ltd. が Redis ライセンスを RSA から BSL(Business Source License)に変更したため、AWS・Google・Linux Foundation が Valkey をスポンサー。

Redis(旧)
  └─ 2024 年 3 月:ライセンス変更(Redis Ltd.)
  └─ 商用利用が制限される可能性

Valkey(新)
  └─ Linux Foundation
  └─ Apache 2.0 ライセンス
  └─ 完全オープンソース
  └─ Redis と API 互換

AWS の推奨方針

時期 ElastiCache MemoryDB
2024 年 10 月 Valkey サポート開始 Valkey サポート開始
2024-2025 Valkey がデフォルト選択肢 Valkey がデフォルト選択肢
2026 年以降 新規は Valkey 推奨 新規は Valkey 推奨

Valkey 採用メリット

  1. ライセンス明確性:完全オープンソース、商用利用制限なし
  2. コスト削減:AWS MemoryDB for Valkey は 30% 低価格
  3. 互換性:Redis API 100% 互換
  4. 将来性:Linux Foundation 支援で長期サポート確保

移行方針

既存 Redis → Valkey への段階的移行:
  1. ElastiCache / MemoryDB で Valkey を試す
  2. 既存 Redis アプリに問題がないか確認
  3. 段階的に Valkey に切り替え
  → 2026 年内に完了推奨

アーキテクチャ

┌─────────────────────────────────────────┐
│   クライアント(Redis ドライバー)         │
│   - redis-py, node-redis, ioredis など   │
└──────────────────┬──────────────────────┘
                   │
        ┌──────────┴──────────┐
        │                     │
┌───────▼─────┐      ┌────────▼──────┐
│ Primary Node │      │ Replica Nodes │
│(読み書き)  │◄─────│(読み取り)    │
│             │      │(最大 5 個)   │
└───────┬─────┘      └────────┬──────┘
        │                     │
        └──────────┬──────────┘
                   │
        ┌──────────▼──────────┐
        │ Multi-AZ            │
        │ Transaction Log      │
        │ - 3 AZ 自動複製     │
        │ - 99.99% 耐久性    │
        └─────────────────────┘

フェイルオーバー:
  Primary 障害 →(< 10 秒)→ Replica が新 Primary に昇格

キーポイント

  • フルマネージド:ノード管理・パッチ自動
  • マルチ AZ:3 AZ にトランザクションログレプリケーション
  • 強整合性:書き込み完了 = 全レプリカで確認
  • 自動フェイルオーバー:< 10 秒で新 Primary 昇格

クラスター構成

シングルノード構成(開発用)

1 Primary ノード
  └─ 開発・テスト環境向け
  └─ SLA なし
  └─ 低コスト

マルチノード構成(本番)

1 Primary + 1~5 Replicas = クラスター
  ├─ Primary: 読み書き
  ├─ Replica 1: 読み取り(AZ-a)
  ├─ Replica 2: 読み取り(AZ-b)
  └─ Replica N: 読み取り(AZ-c)

クラスターモード: 常に有効
  └─ 自動シャーディング(複数ノードでデータ分散)
  └─ スケーリング時の自動リバランシング

スケーリング戦略

段階的スケーリング:

シャード 1: Primary + Replica (容量 A に達した)
  ↓ 容量増加時
新シャード 2・3・... 自動作成
  ↓ 自動リバランシング
データを複数シャードに分散
  → スケーリング完了・ダウンタイムなし

ノードタイプ・スケーリング

ノードタイプ

メモリ容量別:
  db.t4g.small       (  2 GB)  ← 開発用
  db.t4g.medium      (  4 GB)
  db.r7g.large       ( 16 GB)  ← 標準
  db.r7g.xlarge      ( 32 GB)
  db.r7g.2xlarge     ( 65 GB)  ← 大規模
  db.r7g.4xlarge     (130 GB)
  db.r7g.12xlarge    (399 GB)  ← エンタープライズ
  db.r7g.16xlarge    (532 GB)

ネットワーク帯域:
  Graviton 3 ベース(r7g)= 最新・高性能
  Graviton 2 ベース(r6g)= 前世代

Auto Scaling

# Auto Scaling ターゲット設定
aws autoscaling register-scalable-target \
  --service-namespace memorydb \
  --resource-id "cluster/my-cluster" \
  --scalable-dimension "memorydb:cluster:NodeCount" \
  --min-capacity 3 \
  --max-capacity 10

# スケーリングポリシー(CPU 利用率ベース)
aws autoscaling put-scaling-policy \
  --policy-name "scale-memorydb" \
  --service-namespace memorydb \
  --resource-id "cluster/my-cluster" \
  --scalable-dimension "memorydb:cluster:NodeCount" \
  --policy-type "TargetTrackingScaling" \
  --target-tracking-scaling-policy-configuration '{
    "TargetValue": 70.0,
    "PredefinedMetricSpecification": {
      "PredefinedMetricType": "MemoryDBCPUUtilization"
    }
  }'

データ構造・操作

Redis データ構造全対応

String: 単純なキーバリュー
List: 順序付き配列(キュー・スタック)
Set: 一意なメンバーの集合
Hash: フィールド・値のマップ
Sorted Set: スコア付き集合(ランキング)
Stream: メッセージキュー
Bitmap: ビット操作
HyperLogLog: 近似カウント
Geospatial: 地理的位置情報
JSON: JSON ドキュメント(Valkey 拡張)

基本的な操作例

import redis

# Valkey/Redis 接続
r = redis.Redis(
    host='cluster.memorydb.us-east-1.cache.amazonaws.com',
    port=6379,
    ssl=True,
    decode_responses=True
)

# String 操作
r.set('user:1:name', 'Alice')
r.get('user:1:name')  # → 'Alice'

# Hash 操作(ユーザープロファイル)
r.hset('user:1', mapping={
    'name': 'Alice',
    'email': 'alice@example.com',
    'age': 30
})
r.hgetall('user:1')

# Sorted Set(ゲームランキング)
r.zadd('leaderboard', {'player1': 1000, 'player2': 950, 'player3': 900})
r.zrange('leaderboard', 0, 2, withscores=True, rev=True)
# → [('player1', 1000.0), ('player2', 950.0), ('player3', 900.0)]

# Set 操作(タグ・フォロワー)
r.sadd('user:1:tags', 'premium', 'verified', 'early_adopter')
r.smembers('user:1:tags')

# List 操作(メッセージキュー)
r.rpush('notification_queue', 'msg1', 'msg2', 'msg3')
r.lpop('notification_queue')  # → 'msg1'

# Stream(イベントログ)
r.xadd('events', '*', 'user_id', 'user_001', 'action', 'login')
r.xrange('events')

# 有効期限設定(TTL)
r.setex('session:token_abc', 3600, '{"userId": "user_001"}')

Lua Script(複雑な操作)

-- ゲームスコア更新:既存スコアをチェック → 更新
local current_score = redis.call('GET', KEYS[1])
if not current_score or tonumber(current_score) < tonumber(ARGV[1]) then
  redis.call('SET', KEYS[1], ARGV[1])
  redis.call('ZADD', 'leaderboard', ARGV[1], KEYS[1])
  return 1
else
  return 0
end
# Lua Script 実行
script = r.register_script(lua_script)
result = script(keys=['player:1:score'], args=[2500])

永続性メカニズム

マルチ AZ トランザクションログ

Write Request
    ↓
1. Primary ノードのメモリに書き込み
    ↓
2. Multi-AZ Transaction Log に同期書き込み
    │
    ├─ AZ-a: ログ受信
    ├─ AZ-b: ログ受信
    └─ AZ-c: ログ受信
    ↓(過半数確認後)
3. クライアントに成功応答

ノード障害シナリオ:
  Primary 障害 → Transaction Log から復旧
     → Replica が新 Primary に昇格
     → データ損失なし

スナップショット

自動スナップショット:
  毎日指定時刻に S3 へバックアップ
  最大 35 日保持

手動スナップショット:
  オンデマンド作成
  削除まで保持
  別リージョンへの復元可能

PITR(Point-in-Time Recovery):
  非対応(スナップショットから復元)

バックアップ操作

# 手動スナップショット作成
aws memorydb create-snapshot \
  --cluster-name "my-cluster" \
  --snapshot-name "backup-2024-04-26"

# スナップショット一覧
aws memorydb describe-snapshots \
  --cluster-name "my-cluster"

# スナップショットから復元
aws memorydb restore-from-cluster-snapshot \
  --snapshot-name "backup-2024-04-26" \
  --cluster-name "restored-cluster"

# 自動バックアップ設定
aws memorydb update-cluster \
  --cluster-name "my-cluster" \
  --snapshot-retention-limit 35 \
  --snapshot-window "03:00-05:00"

マルチ AZ・フェイルオーバー

マルチ AZ フェイルオーバー

通常運用:
  Primary(AZ-a)← クライアント
  Replica(AZ-b)
  Replica(AZ-c)

AZ-a 障害 →(< 10 秒)→:
  Replica(AZ-b)が新 Primary に昇格
  Replica(AZ-c)のまままたは再起動
  クライアント接続は自動リダイレクト

結果:
  ・ダウンタイム < 10 秒
  ・データ損失なし
  ・アプリケーション再起動不要

フェイルオーバーの設定

# マルチ AZ を有効化(クラスター作成時)
aws memorydb create-cluster \
  --cluster-name "my-cluster" \
  --engine "memorydb" \
  --engine-version "7.0" \
  --num-shards 1 \
  --nodes-to-remove [] \
  --num-replicas-per-shard 2 \
  --node-type "db.r6g.large" \
  --parameter-group-name "default.memorydb" \
  --subnet-group-name "default" \
  --security-group-ids "sg-12345678" \
  --maintenance-window "sun:05:00-sun:06:00" \
  --sns-topic-arn "arn:aws:sns:us-east-1:123456789012:my-topic"

スナップショット・バックアップ

バックアップ戦略

継続的保護:
  トランザクションログ(3 AZ)
    ├─ ノード障害での自動復旧
    └─ < 10 秒フェイルオーバー

定期スナップショット:
  毎日指定時刻
    ├─ S3 へ自動保存
    └─ 35 日保持(カスタマイズ可)

手動スナップショット:
  アップグレード前・セキュリティテスト前など
    ├─ オンデマンド作成
    └─ 長期保存可能

ディザスタリカバリ:
  スナップショット → 別リージョンへ復元
    └─ 地域災害対応

セキュリティ

ネットワークセキュリティ

# VPC・プライベートサブネット配置
aws memorydb create-subnet-group \
  --subnet-group-name "private-subnets" \
  --subnet-ids "subnet-12345678" "subnet-87654321" "subnet-abcdefgh"

# セキュリティグループで制御
aws ec2 create-security-group \
  --group-name "memorydb-sg" \
  --description "MemoryDB access" \
  --vpc-id "vpc-12345678"

# インバウンドルール:ポート 6379 を EC2・Lambda のみ許可
aws ec2 authorize-security-group-ingress \
  --group-id "sg-12345678" \
  --protocol "tcp" \
  --port 6379 \
  --source-security-group-id "sg-app-sg"

IAM 認証・RBAC

# IAM ポリシー例
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "memorydb:DescribeClusters",
        "memorydb:DescribeSubnetGroups"
      ],
      "Resource": "*"
    },
    {
      "Effect": "Allow",
      "Action": [
        "memorydb:Connect"
      ],
      "Resource": "arn:aws:memorydb:*:*:cluster/my-cluster"
    }
  ]
}

# Redis ACL(アクセス制御リスト)
ACL SETUSER reader on >password ~keys:* &@read
ACL SETUSER writer on >password ~keys:* &@write

暗号化

# KMS 暗号化・TLS 有効化(クラスター作成時)
aws memorydb create-cluster \
  --cluster-name "secure-cluster" \
  --tls-enabled true \
  --auth-token "my-secure-token-12345" \
  --kms-key-id "arn:aws:kms:us-east-1:123456789012:key/12345678"

TLS 接続(Python 例)

import redis
import ssl

ssl_context = ssl.create_default_context
ssl_context.check_hostname = False
ssl_context.verify_mode = ssl.CERT_REQUIRED

r = redis.Redis(
    host='cluster.memorydb.us-east-1.cache.amazonaws.com',
    port=6379,
    ssl=True,
    ssl_context=ssl_context,
    password='my-token-12345',
    decode_responses=True
)

r.ping

性能チューニング

CloudWatch メトリクス監視

# CPU 利用率
aws cloudwatch get-metric-statistics \
  --namespace AWS/MemoryDB \
  --metric-name CPUUtilization \
  --dimensions Name=ClusterName,Value=my-cluster \
  --start-time 2024-04-25T00:00:00Z \
  --end-time 2024-04-26T00:00:00Z \
  --period 300 \
  --statistics Average,Maximum

# メモリ利用率
aws cloudwatch get-metric-statistics \
  --namespace AWS/MemoryDB \
  --metric-name DatabaseMemoryUsagePercentage \
  --dimensions Name=ClusterName,Value=my-cluster \
  --statistics Average,Maximum

# ネットワークトラフィック
aws cloudwatch get-metric-statistics \
  --namespace AWS/MemoryDB \
  --metric-name NetworkBytesIn \
  --statistics Sum

クライアント接続最適化

import redis
from redis.connection import ConnectionPool

# コネクションプーリング(推奨)
pool = ConnectionPool(
    host='cluster.memorydb.us-east-1.cache.amazonaws.com',
    port=6379,
    db=0,
    max_connections=100,  # 最大接続数
    socket_keepalive=True,
    socket_keepalive_options={
        1: 1,  # TCP_KEEPIDLE
        2: 1,  # TCP_KEEPINTVL
        3: 3   # TCP_KEEPCNT
    }
)

r = redis.Redis(connection_pool=pool)

# パイプライニング(複数コマンド一括送信)
pipe = r.pipeline(transaction=False)
for i in range(1000):
    pipe.set(f'key:{i}', f'value:{i}')
results = pipe.execute  # 1 回のネットワークトリップで実行

インデックス設計(Sorted Set の活用)

# ❌ 悪い例:全スキャン
def get_top_scores:
    return r.zrange('leaderboard', 0, -1, withscores=True)
    # → メモリ消費大、遅い

# ✅ 良い例:パジネーション
def get_top_scores(page=1, per_page=100):
    start = (page - 1) * per_page
    end = start + per_page - 1
    return r.zrange('leaderboard', start, end, withscores=True, rev=True)
    # → メモリ効率的

# ✅ Sorted Set のスコアで時間範囲検索
r.zrangebyscore('events', min=time.time - 3600, max=time.time)

コスト最適化

コスト構造

月額費用 = ノード費用 + データ転送費

ノード費用:
  db.r6g.large(16 GB): 約 $0.88/時間(月 $640)
  db.r6g.xlarge(32 GB): 約 $1.76/時間(月 $1,280)

Valkey ノード(30% 割引):
  db.r6g.large: 約 $0.60/時間(月 $450)
  → 年間 $2,280 削減

データ転送:
  アウトバウンド: $0.02/GB
  リージョン間: $0.02/GB

コスト削減パターン

# ✅ Valkey に移行(30% コスト削減)
# ❌ Redis → ✅ Valkey

# ✅ ノードタイプ見直し
# 過剰プロビジョニング確認、CPU < 30% なら右サイズ化

# ✅ スナップショット保持期間最適化
aws memorydb update-cluster \
  --cluster-name "my-cluster" \
  --snapshot-retention-limit 7  # 35 日 → 7 日に短縮

# ✅ リードレプリカ数の最適化
# 読み取り分散できれば 1〜2 個で十分

主要ユースケース

ユースケース MemoryDB の強み 実装ポイント
ゲームランキング マイクロ秒 Sorted Set、永続化 ZINCRBY + ZRANGE のパフォーマンス
リアルタイム在庫管理 高速減分・永続化 DECR のアトミック性
セッション管理 TTL 自動削除・強整合性 SETEX で期限設定、フェイルオーバー対応
不正検知(リアルタイム) マイクロ秒クエリ・複雑データ構造 Hash で異常スコア記録、Stream で監査ログ
メッセージング Stream + 永続化 ファイアハウスアーキテクチャ
推奨エンジン JSON + Vector Search AI/ML 統合

設定・操作の具体例

CLI 例

# クラスター作成(マルチ AZ、本番用)
aws memorydb create-cluster \
  --cluster-name "production-cache" \
  --engine "memorydb" \
  --engine-version "7.0" \
  --engine-name-with-version "valkey7.0" \
  --num-shards 2 \
  --num-replicas-per-shard 2 \
  --node-type "db.r6g.xlarge" \
  --parameter-group-name "default.memorydb" \
  --subnet-group-name "private-subnets" \
  --security-group-ids "sg-12345678" \
  --maintenance-window "sun:05:00-sun:06:00" \
  --snapshot-retention-limit 35 \
  --snapshot-window "03:00-04:00" \
  --tls-enabled true \
  --auth-token "MySecureToken123!" \
  --kms-key-id "arn:aws:kms:us-east-1:123456789012:key/key-id" \
  --tags "Environment=production,Owner=DataTeam"

# クラスター確認
aws memorydb describe-clusters \
  --cluster-name "production-cache"

# スケーリング(ノード追加)
aws memorydb update-cluster \
  --cluster-name "production-cache" \
  --node-to-remove "node-id" \
  --apply-immediately

SDK 例(Node.js)

const redis = require('redis');

// クライアント作成
const client = redis.createClient({
  host: 'cluster.memorydb.us-east-1.cache.amazonaws.com',
  port: 6379,
  tls: true,
  password: 'MySecureToken123!',
  socket: {
    keepAlive: 10000,
    noDelay: true
  }
});

client.on('error', (err) => console.log('Redis Client Error', err));

(async  => {
  try {
    await client.connect;

    // Sorted Set でゲームランキング管理
    await client.zAdd('leaderboard', [
      { score: 1000, member: 'player1' },
      { score: 950, member: 'player2' },
      { score: 900, member: 'player3' }
    ]);

    // トップ 10 取得
    const top10 = await client.zRange('leaderboard', 0, 9, {
      WITHSCORES: true,
      REV: true
    });
    console.log('Top 10 Players:', top10);

    // プレイヤースコア更新
    await client.zIncrBy('leaderboard', 50, 'player2');

    // TTL 付きセッション
    await client.set('session:token_abc', JSON.stringify({
      userId: 'user_123',
      ip: '192.168.1.1'
    }), { EX: 3600 });

  } finally {
    await client.quit;
  }
});

Terraform 例

# MemoryDB クラスター
resource "aws_memorydb_cluster" "main" {
  cluster_name       = "production-cache"
  engine_version     = "7.0"
  engine_name        = "valkey"  # Valkey を指定
  node_type          = "db.r6g.xlarge"
  num_shards         = 2
  num_replicas_per_shard = 2
  parameter_group_name = "default.memorydb"

  subnet_group_name = aws_memorydb_subnet_group.main.name
  security_group_ids = [aws_security_group.memorydb.id]

  maintenance_window = "sun:05:00-sun:06:00"
  snapshot_retention_limit = 35
  snapshot_window = "03:00-04:00"

  tls_enabled = true
  auth_token = random_password.memorydb_auth.result

  kms_key_arn = aws_kms_key.memorydb.arn

  tags = {
    Environment = "production"
  }
}

# セキュリティグループ
resource "aws_security_group" "memorydb" {
  vpc_id = aws_vpc.main.id

  ingress {
    from_port   = 6379
    to_port     = 6379
    protocol    = "tcp"
    security_groups = [aws_security_group.app.id]
  }

  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }
}

類似サービス比較

観点 MemoryDB ElastiCache Redis Enterprise Upstash
用途 プライマリ DB キャッシュ エンタープライズ Redis サーバーレス Redis
耐久性 99.99% 限定的 99.99% 99.99%
整合性 強整合性 結果整合 強整合性 結果整合
管理 AWS フルマネージド AWS フルマネージド 自社・AWS サーバーレス
コスト 高(永続性) 中(従量課金)
推奨用途 ランキング・セッション永続化 キャッシュレイヤー エンタープライズ サーバーレス・小規模

ベストプラクティス

インメモリ設計

✅ 推奨パターン

  • Sorted Set でランキング(ゲーム・SNS)
  • Hash でユーザープロファイル
  • Set でタグ・フォロワー管理
  • Stream でイベントログ
  • TTL でセッション自動削除

❌ アンチパターン

  • 大量の String キー(メモリ効率悪)
  • 無制限の List 蓄積(メモリ枯渇)
  • TTL 設定なしのセッション(無限蓄積)

オペレーション

✅ 推奨パターン

  • マルチ AZ 常時有効(本番)
  • 定期スナップショット(35 日保持)
  • CloudWatch アラーム設定(CPU > 80%)
  • Valkey への段階的移行(2026 年まで)
  • Auto Scaling の有効化

❌ アンチパターン

  • シングルノード本番運用(SLA なし)
  • スナップショットなし
  • TLS・auth-token 未設定(セキュリティリスク)
  • Redis + ElastiCache 両運用(管理複雑化)

トラブルシューティング

問題 原因 解決方法
メモリ満杯 データ蓄積・TTL なし TTL 設定、データ削除、ノード追加
写入遅延 ログ確認待ち(マイクロ秒→ミリ秒) 正常動作、スケーリング検討
CPU 100% 負荷集中、クエリ複雑 ノード追加、クエリ最適化
フェイルオーバー失敗 Replica 不足 Replica 数確認、再起動

近年の動向

Valkey デフォルト化

AWS は 2024-2025 年に Valkey をデフォルト化。新規MemoryDB クラスターは Valkey ベースを推奨。既存 Redis ユーザーは段階的移行を検討。

Vector Search 対応予定

ベクトル埋め込みの直接サポートで AI/ML 統合が強化される予定。生成 AI・推奨エンジンでの利用拡大が期待される。

Serverless オプション検討

ElastiCache Serverless に倣って、MemoryDB でのサーバーレスオプション検討中。自動スケーリング・オートスケイリング強化予定。


学習リソース

公式ドキュメント

クライアントライブラリ

AWS リソース


実装チェックリスト

導入前の検討事項

  • [ ] ElastiCache との使い分けを検討(キャッシュ vs プライマリ DB)
  • [ ] DynamoDB との比較(レイテンシ・データ構造の必要性)
  • [ ] Redis/Valkey の既存スキルレベル確認
  • [ ] データサイズの推定(ノードタイプ・シャード数決定)
  • [ ] RPO/RTO 要件の確認(マルチ AZ 必要性)

クラスター構築

  • [ ] VPC・プライベートサブネット設計
  • [ ] セキュリティグループ設定
  • [ ] KMS キー・TLS 暗号化設定
  • [ ] auth-token 生成・安全保管
  • [ ] バックアップ・スナップショット方針決定

開発フェーズ

  • [ ] Redis ドライバー(またはValkey 互換)のセットアップ
  • [ ] コネクションプーリング設定(推奨: 最小 10・最大 100)
  • [ ] データ構造選択(String/Hash/Sorted Set/Stream)
  • [ ] TTL 戦略実装
  • [ ] エラーハンドリング・リトライロジック

本番運用

  • [ ] CloudWatch アラーム設定(CPU・メモリ・ネットワーク)
  • [ ] Auto Scaling の有効化・テスト
  • [ ] 定期バックアップ・復旧テスト
  • [ ] Valkey への段階的移行計画
  • [ ] セキュリティ監査(auth-token、VPC、KMS)

まとめ

Amazon MemoryDB は 「Redis/Valkey 互換のインメモリプライマリデータベース」 で、マイクロ秒読み取り・99.99% 耐久性を両立。ElastiCache(キャッシュ)とは異なり、データ永続化が必須なユースケース(ゲームランキング・セッション・在庫管理)に最適。

選ぶべき場合:

  • Redis/Valkey のデータ構造が必須かつ耐久性も必須
  • マイクロ秒レイテンシーが要件
  • DynamoDB より低レイテンシーが必要
  • 金融・ゲーム・リアルタイムシステム

避けるべき場合:

  • キャッシュのみの用途 → ElastiCache(コスト低)
  • 大規模永続データ(TB 規模)→ DynamoDB/Aurora
  • 複雑 SQL JOIN → RDS/Aurora
  • インメモリ速度不要 → DynamoDB

2025 年の Valkey デフォルト化と Terraform/CloudFormation サポート強化により、採用メリットが一層高まります。既存 Redis ユーザーは段階的移行で、AWS ネイティブな超低レイテンシー永続 DB の恩恵を受けられます。