シャーディング

データを複数のデータベースインスタンスに水平分割し、書き込みスループットとストレージ容量をスケールさせる手法

データベーススケーリング

シャーディングとは

シャーディング (Sharding) は、データを複数のデータベースインスタンス (シャード) に水平分割し、書き込みスループットとストレージ容量をスケールさせる手法である。1 台の DB では処理しきれないデータ量やトラフィックに対応する。

シャーディング前: 1 台の DB に全データ
シャーディング後:
  シャード 0: userId 0〜999
  シャード 1: userId 1000〜1999
  シャード 2: userId 2000〜2999

シャーディング戦略

戦略 仕組み メリット デメリット
ハッシュ キーのハッシュ値で分割 データが均等に分散 範囲クエリが非効率
レンジ キーの範囲で分割 範囲クエリが効率的 ホットスポットが発生しやすい
ジオベース 地理的に分割 レイテンシ最適化 地域間クエリが複雑
ディレクトリ ルックアップテーブルで分割先を決定 柔軟な分割 ルックアップが単一障害点

DynamoDB の自動シャーディング

DynamoDB は内部的にシャーディングを自動で行う。パーティションキーのハッシュ値でデータを分散し、パーティション数はデータ量とスループットに応じて自動増加する。

// パーティションキーの設計が重要
// ❌ 悪い例: 日付をパーティションキーにすると、今日のパーティションに集中
{ PK: '2026-04-01', SK: 'order-123' }

// ✅ 良い例: userId をパーティションキーにすると、ユーザーごとに分散
{ PK: 'user-456', SK: 'order-123' }

RDS vs DynamoDB のシャーディング

観点 RDS DynamoDB
シャーディング 手動 (アプリケーション側) 自動 (パーティションキー)
リバランス 手動 自動
クロスシャードクエリ 複雑 (全シャードに問い合わせ) GSI で対応
トランザクション 分散トランザクション (2PC) が必要 TransactWriteItems で 100 項目まで

シャーディングの課題

クロスシャードクエリ

複数のシャードにまたがるクエリ (JOIN、集計) は、全シャードに問い合わせて結果をマージする必要がある。

「全ユーザーの注文合計」→ 全シャードに問い合わせ → 結果をマージ
「userId=123 の注文」→ シャード 0 だけに問い合わせ (効率的)

リシャーディング

データ量の増加に伴いシャード数を増やす場合、既存データの再配置が必要になる。コンシステントハッシュを使えば、再配置するデータ量を最小限に抑えられる。

トランザクション

複数シャードにまたがるトランザクションは、分散トランザクション (2PC) が必要になり、複雑さとレイテンシが増大する。

シャーディングを避ける方法

シャーディングは複雑さを大幅に増すため、他の手段で対応できないか先に検討する。

  1. リードレプリカ: 読み取り負荷の分散
  2. キャッシュ (ElastiCache): 頻繁に読まれるデータをキャッシュ
  3. インデックスの最適化: クエリパフォーマンスの改善
  4. DynamoDB: 自動パーティショニングでシャーディングが不要

DynamoDB を使えば、アプリケーション側でシャーディングを実装する必要がない。パーティションキーの設計だけに集中すればよい。

体系的に学ぶなら関連書籍を参照してほしい。

関連用語