レンジシャーディングとハッシュシャーディングの戦略
範囲クエリにはレンジシャーディングを、均一な書き込み分散にはハッシュシャーディングを使うようコレクションを構成し、それぞれのトレードオフを比較します。
「レンジシャーディングとハッシュシャーディングの戦略」はCoddyKit上の無料MongoDB Academyレッスンです。 これはレッスン3/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはMongoDB Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 MongoDB Academyコースには全4レッスンが含まれています。
2つのシャーディング戦略の比較
MongoDBには、組み込みのシャーディング戦略として範囲シャーディングとハッシュシャーディングの2つがあります。範囲シャーディングは、シャードキー値の連続した範囲を特定のシャードに割り当てます。ハッシュシャーディングは、まずキーにハッシュ関数を適用し、そのハッシュに基づいて分散します。どちらにも異なる強みがあり、適切な選択はデータアクセスパターンによって決まります。
範囲シャーディング:仕組み
範囲シャーディングでは、MongoDBがシャードキーの値域を連続した範囲に分割し、各範囲(チャンク)をシャードに割り当てます。たとえば、userIdが1~10,000のユーザーをシャードAに、10,001~20,000のユーザーをシャードBに割り当てるといった具合です。シャードキーの値が近いドキュメントは同じシャードに配置されるため、範囲クエリに適しています。
// Enable ranged sharding on a field
sh.shardCollection('mydb.products', { category: 1, price: 1 })
// Range query is now targeted to the shard(s) holding that range
db.products.find({ category: 'electronics', price: { $lt: 100 } })範囲シャーディング:強み
範囲シャーディングは、アプリケーションが値の範囲を頻繁にクエリする場合に優れています。たとえば、日付範囲、価格範囲、アルファベット順の名前の範囲、数値IDで並べ替えたページネーション結果などです。隣接する値が同じ場所に配置されるため、範囲クエリは1つまたは少数のシャードだけにアクセスするターゲットクエリとなり、レイテンシーを低く保てます。
// With ranged sharding on { orderId: 1 }, this is targeted:
db.orders.find({
orderId: { $gte: 50000, $lte: 60000 }
})
// mongos knows exactly which shard owns this range範囲シャーディング:弱点 — ホットスポット
範囲シャーディングの重大な弱点は、シャードキーが単調増加する場合(タイムスタンプ、自動インクリメントID、ObjectIdなど)に書き込みホットスポットが発生することです。新しいドキュメントはすべて範囲の上限側に集中し、1つのシャードに配置されます。バランサーがチャンクを移行するまで、そのシャードがすべての書き込みトラフィックを処理し、他のシャードはアイドル状態になります。
// Problematic: all new events go to the max-range shard
sh.shardCollection('mydb.events', { createdAt: 1 }) // ranged, monotonic = hot spot
// Production symptom: one shard has 90%+ of recent data
// and absorbs all write IOPSハッシュシャーディング:仕組み
ハッシュシャーディングでは、MongoDBがシャードキーの値をハッシュ化し、そのハッシュを使ってチャンクを決定します。元のキーが単調増加していても、ハッシュ値はランダムに見えるため、ドキュメントはハッシュ値に基づいて分散されます。これにより、初期書き込みがすべてのシャードにほぼ均等に分散されます。
// Hashed sharding on _id (neutralizes ObjectId monotonicity)
sh.shardCollection('mydb.events', { _id: 'hashed' })
// Hashed sharding on userId
sh.shardCollection('mydb.sessions', { userId: 'hashed' })ハッシュシャーディングの長所
ハッシュシャーディングは、シャード間で書き込みを均等に分散することが主な目的で、シャードキーに対する範囲クエリが不要な場合に最適です。単調なキーを使用する高頻度の挿入ワークロード(イベントログ、IoTセンサーデータ、メッセージングなど)で、すべてのシャードに書き込み負荷を均等に分担させたい場合に適しています。
// With hashed sharding, inserts are spread uniformly:
// doc1 (hash: 2345...) -> shard A
// doc2 (hash: 8901...) -> shard C
// doc3 (hash: 4567...) -> shard B
// No hot spot regardless of insert orderハッシュシャーディングの弱点:範囲クエリの効率が低い
ハッシュシャーディングのトレードオフは、シャードキーに対する範囲クエリがscatter-gatherになることです。隣接するハッシュ値が複数のシャードに分散するため、{ createdAt: { $gte: t1, $lte: t2 } }のようなクエリは、すべてのシャードに処理を分散させる必要があります。範囲クエリを頻繁に実行し、レイテンシーが重要な場合、ハッシュシャーディングによってシャーディングの性能向上が相殺される可能性があります。
// With hashed sharding on createdAt:
// Range query CANNOT be targeted — fans out to all shards
db.events.find({ createdAt: { $gte: ISODate('2025-01-01'), $lte: ISODate('2025-02-01') } })
// Equivalent to a full collection scan across all shardsレンジシャーディングとハッシュシャーディングの選択
判断の目安:レンジシャーディング → シャードキーが自然に分散しており(単調増加ではなく)、主要なクエリがそのキーに対する範囲クエリである場合。ハッシュシャーディング → シャードキーが単調増加する場合、または主要なクエリがカーディナリティの高いフィールドに対するポイント検索(等価検索)である場合。迷ったときに挿入がボトルネックであれば、ハッシュシャーディングを優先してください。
ハイブリッド:ハッシュコンポーネントを含む複合キー
両方の方式を、先頭フィールドをレンジ方式にしてクエリの局所性を確保し、2番目のフィールドにハッシュ方式を追加する複合シャードキーで組み合わせることができます。例:{ tenantId: 1, _id: 'hashed' }では、テナントごとにデータを近接配置しながら、各テナント内でシャード間に書き込みを分散できます。
// Ranged tenantId + hashed _id within tenant
// Writes are distributed; per-tenant queries are targeted
sh.shardCollection('mydb.events', { tenantId: 1, _id: 'hashed' })
// Targeted: all tenantId queries go to the right shard(s)
db.events.find({ tenantId: 'acme', _id: ObjectId('...') })使用中の方式を確認する
コレクションのシャーディング設定を調べることで、使用中の方式を確認できます。config serverのメタデータにはシャードキーと、'hashed'を使用しているかどうかが保存されています。sh.status()コマンドとdb.collection.stats()のどちらでも、この情報を確認できます。
// Check sharding info for a collection
use config
db.collections.findOne({ _id: 'mydb.events' })
// { key: { _id: 'hashed' }, unique: false, ... }
// Or via sh.status()
sh.status()一括ロード用のチャンクの事前分割
新しくシャーディングしたコレクションにデータを一括ロードする場合、最初はすべてのチャンクが1つのシャードに存在し、balancerによる移行が必要になります。これは時間がかかる場合があります。事前分割では、ロード前に空のチャンクを作成し、すべてのシャードに分散させます。これにより、balancerの作業を最小限に抑え、最初の挿入から書き込みを分散できます。
// Pre-split chunks for ranged sharding
// Define desired split points and assign to shards
db.adminCommand({ split: 'mydb.events', middle: { userId: 500000 } })
db.adminCommand({ moveChunk: 'mydb.events',
find: { userId: 500000 }, to: 'shard02' })理解度チェック
このレッスンで学んだMongoDBとNoSQLデータベースの概念について、理解度を確認しましょう。
レッスンのまとめ
このレッスンでは、レンジシャーディングは類似したキー値を近接配置して範囲クエリを効率化する一方、単調なキーではホットスポットを発生させること、ハッシュシャーディングはシャード間に均等に分散する一方、範囲クエリをscatter-gatherにすること、そして複合キーによって両方の利点を組み合わせられることを学びました。次は、データを特定のリージョンに固定するゾーンシャーディングについて学びます。
AI チューターと学ぶ JavaScript — 無料
ブラウザでリアルコードを書いて実行し、24/7 の AI チューターから瞬時にサポートを受け、ウェブまたはアプリで続きから学習できます。
- コース
- 30
- レッスン
- 120
よくある質問
「レンジシャーディングとハッシュシャーディングの戦略」レッスンは無料ですか?
はい。「レンジシャーディングとハッシュシャーディングの戦略」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、MongoDB Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 MongoDB Academyコースには全4レッスンが含まれています。
「レンジシャーディングとハッシュシャーディングの戦略」で何を学びますか?
範囲クエリにはレンジシャーディングを、均一な書き込み分散にはハッシュシャーディングを使うようコレクションを構成し、それぞれのトレードオフを比較します。 ブラウザで直接実行するハンズオンコードでMongoDB Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
MongoDB Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのMongoDB Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン3/4です。
「レンジシャーディングとハッシュシャーディングの戦略」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このMongoDB Academyレッスンでコードを書いて実行できますか?
はい。すべてのMongoDB Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- シャーディングの概念:チャンク、バランサー、シャードキー
- シャードキーの選択:カーディナリティ、頻度、単調性
- レンジシャーディングとハッシュシャーディングの戦略
- ゾーンシャーディング:データのリージョン固定