---
title: パーティショニング戦略
url: https://doc.liz6.com/ja/distributed-systems/04-partitioning-and-routing/02-sharding-strategies
locale: ja
area: distributed-systems
tags:
- distributed-systems
- partitioning-and-routing
date: 2026-06-30
modified: 2026-07-16
description: データをどのようにパーティショニングするかが、クエリのルーティング方法、負荷の分散度、そしてスケールアウト時のデータ移行量を決めます。レンジパーティショニングは範囲クエリには有利ですがホットスポットが発生しやすく、ハッシュパーティショニングは均一ですが範囲クエリには扇状展開が必要です。万能薬はなく、アクセスパターンに応じた選択が重要です。
---

# パーティショニング戦略

> データをどのようにパーティショニングするかが、クエリのルーティング方法、負荷の分散度、そしてスケールアウト時のデータ移行量を決めます。レンジパーティショニングは範囲クエリには有利ですがホットスポットが発生しやすく、ハッシュパーティショニングは均一ですが範囲クエリには扇状展開が必要です。万能薬はなく、アクセスパターンに応じた選択が重要です。

## レンジパーティショニング

キーの文字/数値の区間に基づいてシャードを割り当てます。百科事典の巻分けに似ています：A-D → シャード 1、E-H → シャード 2、...

利点：
- **レンジスキャンが効率的**: `WHERE key BETWEEN 'a' AND 'c'` のようなクエリでは、1つのシャードのみをアクセスすればよい
- **シーケンシャル書き込みが連続**: 最新のキーは同じシャードに配置されるため → シーケンシャル IO

欠点：
- **ホットスポット**: 特定のキー範囲（例：最新のタイムスタンプ）が頻繁にアクセスされると、そのシャードがボトルネックになる
- **偏った分布**: データの分布が偏る可能性がある（特定のアルファベット範囲のデータが多い場合など）

適用例：HBase, Bigtable, MongoDB のレンジパーティショニング。

## ハッシュパーティショニング

`shard = hash(key) % N` — 全シャードに均一に分散される。

利点：負荷分散が実現され、ホットスポットが発生しない（キーの分布が均一であると仮定）。欠点：**レンジスキャンの喪失** — 連続するキーが全シャードに分散されるため → レンジクエリでは全シャードへの扇状展開（scatter-gather）が必要になる。

適用例：Cassandra (Murmur3), DynamoDB (MD5)。Cassandra のパーティションキーは `hash(key)` だが、同じパーティション内ではクラスタリングカラムによるレンジスキャンがサポートされている。

## リバランシング

ノード数が変更された際のデータ再割り当て：

**固定パーティション数**: 作成時に固定数のパーティション（例：1000）を割り当て、各ノードが複数のパーティションを担う。ノード追加時 → 既存ノードから一部のパーティションを新規ノードに移行。利点：シンプルで、移行コストを均等に分散できる。欠点：パーティション数を設定後、変更が難しい（データ量がパーティション数 1000 を大幅に超えて増えた場合など）。

**動的パーティショニング**: パーティションはデータ量が閾値を超えた場合に分割（split）し、閾値を下回った場合にマージ（merge）できる。データ量の変化に適応できるが、分割時のパフォーマンスへの影響がある。

## ホットスポットの緩和

特定のキーが極めて高い頻度でアクセスされる → 所在するシャードがボトルネックになる。緩和策：

- **キーのソルティング**: `key = original_key + random_salt` → 異なるシャードに分散される。読み取り時はすべてのソルトバリエーションから読み取り、結果を結合する。
- **キャッシュ**: 熱いキーをアプリケーション層でキャッシュする（Redis/Memcached）
- **パーティション認識型クライアント**: クライアントがどのシャードに熱いキーがあるかを知っている → 中間層を介さず直接そのシャードに接続 → 1ホップ節約

## シャーデッドデータ上のセカンダリインデックス

```
グローバルセカンダリインデックス (DynamoDB):
  インデックスはメインテーブルのパーティショニングとは独立 → 独自のパーティションキーを持てる
  書き込み: メインテーブルへの書き込み + インデックスの非同期更新（一時的な不整合が発生する可能性あり）
  読み取り: インデックスが直接ターゲットシャードを指す

ローカルセカンダリインデックス (Cassandra):
  インデックスはメインテーブルと同じパーティション内に存在
  書き込み: 原子性（同じパーティション内であれば、パーティションを跨ぐトランザクションは不要）
  読み取り: パーティションキーの指定が必要 → 単一のパーティションのみスキャン可能
```

## 参考

- **Cassandra**: cassandra.apache.org/doc/stable/cassandra/architecture/dynamo.html
- **DynamoDB**: docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.Partitions.html

*キーワード: レンジパーティショニング, ハッシュパーティショニング, リバランシング, ホットスポット, キーソルティング, セカンダリインデックス, Cassandra, DynamoDB*
