MongoDB でのロック
データベース管理システムでは、ロック メカニズムによって結果全体の一貫性が確保されます。
たとえば、データに対して何らかの write
手順が実行されている場合、read
コマンドを同時に実行することはできません。 このような状況によるデータの不正確さを防ぐために、データベース リソースはロック
されています。
また、複数のクライアントが同じデータに同時にアクセスまたは変更できるため、MongoDB はロックを使用してデータの一貫性を確保します。 この記事では、MongoDB におけるロックの概念について説明します。
MongoDB でのロック
MongoDB でのロックは、他のリレーショナル データベース管理システムでのロックとは異なる方法で機能します。 MongoDB でロックがどのように機能するかを説明しましょう。
MongoDB は マルチグラニュラリティ ロック
を利用します。 これは、プロセスをグローバル、データベース、またはコレクション レベルで、さらには個々のストレージ エンジンのドキュメント レベルでロックできることを意味します。
これらのレベルのロックについては、この記事で詳しく説明します。 v2.2 以降の最近のバージョンの MongoDB では、データベースごとにリーダー/ライター ラッチが存在します。
これらのリーダー/ライター ラッチにより、データベース リソースへの同時アクセスが可能になります。 これらがどのように機能するかを説明しましょう。
リーダー/ライター ラッチ
MongoDB のリーダー/ライター ラッチには、次のプロパティがあると最もよく説明できます。
-
マルチリーダー
です。 つまり、データは変更されておらず、読み取り専用であるため、データの一貫性に影響を与えることなく、任意の数のリーダーがコレクションに同時にアクセスできます。 -
シングルライター
です。 これは、データの一貫性を確保するために、一度に 1つのライターしか存在できないことを意味します。 -
欲張りな作家
です。 貪欲な作家であることは、読者よりも作家が優先されることを意味します。したがって、ライターがデータベースの使用を要求すると、受信したすべてのリーダーは、ジョブが完了するまで一時的にブロック (またはロックアウト) されます。
ただし、ライターは現在のリーダーが離れるまで待機します。 この実装により、ライターが無期限に枯渇するのを防ぎます。
注: リーダー/ライター ラッチは、リーダー/ライター ロックと呼ばれます。 ただし、軽量であるため、ラッチと呼ぶ方が適切です。
MongoDB にこのラッチが存在するため、大規模なロックの競合なしに同時クエリを実行できます。
ここでライター ラッチが興味深いのは、MongoDB では、1つのドキュメントへのすべての書き込み操作がアトミックと見なされるためです。 write
操作はアトミックであるため、MongoDB カーネルによってライター ラッチが保持されるのは、1つのドキュメントを更新するのにかかる時間だけです。
したがって、実行速度の遅い write
操作が実行された場合 (たとえば、不適切なスキーマ設計やディスクからのドキュメントのページングが原因で)、ラッチが発生したと言われます。
もう 1つ注意すべき点は、前述のように、MongoDB にはデータベースごとに個別のリーダー/ライター ラッチがあることです。 これを説明するために、A と B という 2つのデータベースがあるとします。
データベース A での write
操作の場合、ライターはデータベース B での write
操作とは別のラッチを取得します。
同様に、データベースへの複数の接続が同時に 書き込み
操作を実行する場合、ラッチはデータベースごとに保持されます。 さらに、これらの同時接続はインターリーブされます。
注: ロックが原因で、データベース システムのパフォーマンスと速度が影響を受けているように感じるかもしれません。 実際には、平均的な負荷の場合、データベースのロック率が 50% を超える前に MongoDB がディスクまたは SSD の I/O 容量を飽和させるため、これはあまり問題ではありません。
したがって、MongoDB でのロックは接続ごとではないと言います。 むしろ、それは mongod
ごとです。
mongod
は、MongoDB システムの主要なバックグラウンド プロセスを指し、データ リクエスト、データ アクセス、およびその他のバックグラウンド操作を管理します。
MongoDB でのロックのレベル
MongoDB には、次の 4つのレベルのロックがあります。
グローバルレベルのロック
: これは、インスタンスレベルのロックとも呼ばれます。 これは、すべてのデータベースがロックされることを意味します。データベースレベルのロック
: このタイプのロックでは、指定されたデータベースのみがロックされます。コレクションレベルのロック
: MongoDB では、コレクションは関連するドキュメントのグループです (従来の RDBMS のテーブルに似ています)。 コレクション レベルのロックは、個々のコレクションのロックを処理します。ドキュメントレベルのロック
: MongoDB のドキュメントは、フィールドと値のペアを持つレコードとして参照できます。 このタイプのロックは、特定のドキュメントのみをロックします。
MongoDB でのロックのモード
MongoDB には、以下で説明する 4つのロック モードがあります。
-
R
:共有 (S)
ロックを表します。 このロック モードはリーダーに使用されます。リソースはリーダー間で共有され、このモードで同時にアクセスします。
-
W
:排他的 (X)
ロックを表します。 このロック モードはライターに使用されます。このモードでは、他の同時リーダーまたはライターがリソースを使用することはできません。
-
r
:Intent Shared (IS)
ロックを表します。 より高度なインテント ロックです。このようなロックは、下位レベルのロックに移動する前に取得されます。 たとえば、
r
ロックがデータベース レベルで取得された場合、R
ロックがコレクションおよびドキュメント (下位) レベルで取得できるようになったことを意味します。 -
w
:Intent Exclusive (IX)
ロックを表します。 これは、より高度なインテント ロックでもあります。r
ロックの仕組みと同様に、w
ロックがデータベース レベルで取得された場合、コレクションおよびドキュメント (下位) レベルでW
ロックを取得できるようになったことを意味します。
MongoDB でロック状態を確認する
では、mongod
インスタンスのロックの状態を確認する方法はありますか? はい、次の方法を使用して行うことができます。
db.serverStatus()
この方法を使用して、さまざまなレベルでロックを監視できます。次に例を示します。
- グローバル レベルでは、このコード
db.serverStatus().globalLock
を使用します。 - データベース レベルでは、このコード
db.serverStatus().locks.Database
を使用します。 - コレクション レベルでは、このコード
db.serverStatus().locks.Collection
を使用します。 oplog
(操作ログ) でロックを監視するには、このコードdb.serverStatus().locks.oplog
を使用します。
次の方法も使用できます。
db.currentOp()
まとめ
この記事では、MongoDB でのロックの概念について説明し、続いてそのさまざまなレベルとモードについて説明しました。 これらの概念を理解していただければ幸いです。
Hello, I am Bilal, a research enthusiast who tends to break and make code from scratch. I dwell deep into the latest issues faced by the developer community and provide answers and different solutions. Apart from that, I am just another normal developer with a laptop, a mug of coffee, some biscuits and a thick spectacle!
GitHub