Amazon DynamoDB
フルマネージドのサーバーレスNoSQL。一桁ミリ秒の応答とほぼ無限のスケールを、運用なしで実現する。
- サーバー管理ゼロで一桁ミリ秒・ほぼ無限に伸びるNoSQL。
- PKをハッシュして自動でパーティション分割しスケールする。
- アクセスパターン駆動でキー設計、スパイクはオンデマンド。
解決する課題
- アクセスが急増しても落ちない/遅くならないDBが欲しい
- DBの容量計画・シャーディングを自分でやりたくない
- ミリ秒の応答を安定して出したい
主要概念と用語
- テーブル / 項目(Item)/ 属性(Attribute)
- パーティションキー(PK): データの分散先を決める最重要キー
- ソートキー(SK): 同一PG内の並び/範囲検索
- GSI / LSI: 別の属性で検索するためのインデックス
- 容量モード: オンデマンド / プロビジョンド
- DynamoDB Streams: 変更をイベントとして流す(Lambda連携)
- TTL / DAX: 自動失効 / マイクロ秒キャッシュ
仕様・制限・クォータ
| 項目 | 値 |
|---|---|
| 1項目のサイズ | 400KB(属性名も含む) |
| パーティションキーの値 | 2,048バイト |
| ソートキーの値 | 1,024バイト |
| 1パーティションの上限 | 3,000 RCU / 1,000 WCU / 10GB |
| LSI | テーブルあたり5・作成時のみ追加可 |
| GSI | テーブルあたり20(引き上げ可)・後から追加可 |
| BatchGetItem | 100項目 または 16MB |
| BatchWriteItem | 25項目 |
| Query / Scan の1回の応答 | 1MB(続きは LastEvaluatedKey でページング) |
- 表とLSIは結果整合性(デフォルト)と強い整合性を選べる。GSIは結果整合のみ
- DAXは結果整合の読取をキャッシュし、強い整合要求はDynamoDBへ通過
- マルチAZへ自動複製、グローバルテーブルで多リージョン化
400KB を超えるデータは入りません。 本体を S3 に置いてキーだけを項目に持たせる形に変えます。
RCU / WCU の数え方
キャパシティの単位は、サイズと整合性で換算が変わります。ここを知らずに プロビジョンド値を決めると、必ず足りないか余ります。
| 操作 | 消費 |
|---|---|
| 強い整合性の読み取り | 1 RCU = 4KB まで / 1回 |
| 結果整合性の読み取り | 1 RCU = 4KB まで / 2回(半分で済む) |
| トランザクション読み取り | 4KB あたり 2 RCU |
| 書き込み | 1 WCU = 1KB まで / 1回 |
| トランザクション書き込み | 1KB あたり 2 WCU |
端数は切り上げです。6KB の項目を強い整合性で読むと 2 RCU、書くと 6 WCU。 読みは4KB刻み、書きは1KB刻みという非対称を覚えておくと見積もりが速くなります。
キャパシティモードは2つあります。
- オンデマンド — 設定不要で使った分だけ。トラフィックが読めない、スパイクする、開発中はこれ。
- プロビジョンド — RCU/WCU を指定。Auto Scaling と組み合わせられ、定常負荷では明確に安い。 さらに Reserved Capacity で追加割引が効きます。
判断は「予測できるか」で分かれます。定常的に動くワークロードをオンデマンドのまま放置している、 というのがコスト超過でよくある形です。
パーティションキー設計が性能を決める
DynamoDB の性能問題は、ほぼすべてキー設計に由来します。
データはパーティションキーのハッシュで分散されます。1つのパーティションには 3,000 RCU / 1,000 WCU の上限があるため、キーの値が偏るとテーブル全体の キャパシティに余裕があってもそこだけ詰まります(ホットパーティション)。
避け方は、キーの値が散るように設計することです。
日付をパーティションキーにすると、その日のアクセスが1パーティションに集中します。日付#ユーザーIDのように複合させて散らします。- 連番のIDは、書き込みが末尾に集まる形になりやすいので、接頭辞を付けて分散させます。
Adaptive Capacity が偏りを自動で緩和しますが、瞬間的な集中には追いつきません。 設計で散らすのが本筋です。
GSI と LSI の違い
「別の属性で検索したい」となったときに選ぶものですが、性質がかなり違います。
| LSI(ローカル二次インデックス) | GSI(グローバル二次インデックス) | |
|---|---|---|
| パーティションキー | テーブルと同じ | 別のものを指定できる |
| 作成タイミング | テーブル作成時のみ | あとから追加・削除できる |
| 整合性 | 強い整合性を選べる | 結果整合性のみ |
| キャパシティ | テーブルと共有 | インデックス専用に別途 |
| 制限 | パーティションあたり10GB | なし |
実務では ほぼ GSI を使います。LSI はテーブル作成時にしか作れず、 10GB の制限が後から効いてくるためです。
GSI は独自のキャパシティを持ちます。GSI 側が書き込みスロットリングを起こすと、
テーブルへの書き込み自体が失敗します(インデックスに反映できないため)。
テーブルだけ監視していて GSI を見ていないと、原因の分からない ProvisionedThroughputExceededException になります。
Query と Scan
- Query — パーティションキーの指定が必須。該当するパーティションだけを読むので効率的。
- Scan — テーブル全体を読みます。フィルタ式を付けても読んだ分のRCUは消費されます (フィルタは読んだ後に絞るだけ)。
「フィルタを付けたのにキャパシティを使い切った」というのは、この誤解が原因です。 検索条件が変わったなら Scan にフィルタを足すのではなく、GSI を作って Query にします。
内部の仕組み
DynamoDBはPKをハッシュして内部パーティションへ分散します。アクセスが増えると自動でパーティションを分割しスケール。ゆえにPK設計=性能設計で、特定キーに偏るとホットパーティションで詰まります。
横にスクロール
RDBの正規化ではなくアクセスパターン駆動設計。「どう問い合わせるか」を先に決めてキー/インデックスを設計する(シングルテーブル設計が定番)。
設計パターン / ベストプラクティス
- アクセスパターンを列挙 → PK/SK と GSI を設計
- スパイクが読めないなら オンデマンド 容量
- 変更駆動の処理は Streams → Lambda
- 読み取りが激しいなら DAX でキャッシュ
運用・監視・トラブルシュート
- メトリクス:
ConsumedRead/WriteCapacityThrottledRequests - スロットルはホットパーティション or 容量不足を疑う
- 大量読み取りの Scan は避け、Query で絞る
コスト
- 読み書きキャパシティ(オンデマンド/プロビジョンド)+ストレージ
- 定常負荷はプロビジョンド+Auto Scalingが安いことも
セキュリティ
- 保存時暗号化はデフォルト(KMS)
- IAMで項目/属性レベルまで条件付与可能
- VPCからはゲートウェイ型VPCエンドポイントで到達
Well-Architected の観点
- パフォーマンス効率: 一桁ミリ秒・自動スケール
- 信頼性: マルチAZ複製・グローバルテーブル
- コスト最適化: 容量モードの使い分け
試験で問われるポイント
- アクセスパターン駆動のキー設計、ホットパーティション回避
- 別属性検索=GSI(作成後も追加可)/ LSIは作成時のみ
- スパイク=オンデマンド、変更連携=Streams
DynamoDBのテーブル設計で最も重要な考え方は?
関連サービス・比較
| 観点 | DynamoDB | RDS/Aurora |
|---|---|---|
| モデル | NoSQL(キーバリュー/ドキュメント) | リレーショナル(SQL) |
| スケール | 水平・ほぼ無限・自動 | 縦+リードレプリカ |
| クエリ | キー中心(JOINなし) | 柔軟なSQL/JOIN |
| 運用 | サーバーレス | マネージド(設定多め) |
ハンズオン / CLI例
# オンデマンド課金でテーブル作成(PK=userId, SK=createdAt)
aws dynamodb create-table \
--table-name Orders \
--attribute-definitions AttributeName=userId,AttributeType=S AttributeName=createdAt,AttributeType=S \
--key-schema AttributeName=userId,KeyType=HASH AttributeName=createdAt,KeyType=RANGE \
--billing-mode PAY_PER_REQUEST
# 1ユーザーの注文を範囲検索(Scanではなく Query)
aws dynamodb query --table-name Orders \
--key-condition-expression "userId = :u" \
--expression-attribute-values '{":u":{"S":"user-123"}}'
AWS Service
Amazon DynamoDBを実務で読む
TL;DRは入口です。実際に選ぶ・使う段階では、何を解決するか、何と比較するか、導入後にどこで詰まるかまで見る必要があります。
解決すること
データベース
比較で見る軸
クラウド: AWS / カテゴリ: データベース / 難易度: intermediate
導入後に効く点
PKをハッシュして自動でパーティション分割しスケールする。
先に潰すリスク
サービス単体ではなく、権限、ネットワーク、監視、課金、バックアップを含めて設計する必要がある。
- クラウド
- AWS
- カテゴリ
- データベース
- 難易度
- intermediate
- 関連資格
- SAA-C03 / DVA-C02 / SAP-C02
- 設計柱
- performance / reliability / cost
判断チェックリスト
- 自社の用途が「データベース / performance」に近いか確認する。
- 強みである「サーバー管理ゼロで一桁ミリ秒・ほぼ無限に伸びるNoSQL。」が本当に評価軸になるか確認する。
- 注意点の「サービス単体ではなく、権限、ネットワーク、監視、課金、バックアップを含めて設計する必要がある。」を運用で吸収できるか確認する。
- 公開値や仕様値は、対象プラン・対象機種・対象リージョンまで確認する。
- 既存システム、ID、ネットワーク、監視、バックアップとの接続方法を先に洗い出す。
- 小さく試してから、本番移行、権限設計、障害時手順、コスト監視を決める。
他クラウドの同等サービス
役割が近いサービスです。設計の置き換えや比較検討の参考に。