非常に高い書き込みスループットと妥当な読み取りスループットを必要とするデータベースをモデル化しようとしています。「イベント」データをデータベースに追加するシステムの分散セットがあります。
現在、イベントレコードのIDはGuidです。GUIDはランダムに分布しているため、最近のデータがディスクに分散し、ページングの問題が発生する可能性があるため、GUIDは優れたインデックスを作成する傾向がないことを読んでいます。
したがって、検証したい最初の仮定は次のとおりです。自動番号のようなものなど、適切なバランスの取れたツリーを作成する_idを選択したくないと仮定しています。最近の2つのイベントは基本的にディスク上で隣り合っているため、これは有益です。これは正しい仮定ですか?
(1)が正しいと仮定して、私はそのようなIDを生成するための最良の方法を見つけようとしています。MongoがObjectIdをネイティブにサポートしていることは知っています。これは、データをMongoに結び付けても問題ないアプリケーションに便利ですが、私のアプリケーションはそうではありません。データを生成するシステムは複数あるため、mongoはサーバー側で自動番号をサポートしていないため、「自動番号」フィールドのシミュレーションは少し問題があります。そのため、プロデューサーはIDを割り当てる必要があります。他のシステムが何をしているのかわからない。
これを解決するために、私が検討しているのは、_idフィールドを{localId、producerId}の複合キーにすることです。ここで、local idは、producerIdによって一意になるため、プロデューサーが生成できる自動番号です。ProducerIdは、プロデューサー間でネゴシエートして、一意のIDを考え出すことができるものです。
次の質問です。すべてのプロデューサーから最新のデータを取得することが目標の場合、localIdは右向きで、producerIdは小さなクラスターになるため、{localId、producerId}を優先キーの順序にする必要があります。最近の2つのイベントは互いにローカルのままであることが望ましいでしょう。その順序を逆にすると、ツリーが最終的にどのように見えるかについての私の推論は次のようになります。
root
/ | \
p0 p1 p2
/ | \
e0..n e0..n e0..n
ここで、p#はプロデューサーID、e#はイベントです。これは、インデックスをデータのp#クラスターに断片化するようであり、新しいイベントは必ずしも互いに隣接しているとは限りません。優先順位に関する私の仮定は、代わりに次のようになります(確認してください)。
root
/ | \
e0 e1 e2
/ | \
p0..n p0..n p0..n
最近の出来事を互いに近づけているようです。(MongoがインデックスにBツリーを使用していることは知っていますが、ここではビジュアルを単純化しようとしています)。
私が見ることができる{localId、producerId}の唯一の注意点は、ユーザーによる一般的なクエリは、プロデューサーごとに最新のイベントをリストすることであり、{producerId、localId}は実際にははるかにうまく処理できるということです。このクエリを{localId、producerId}で機能させるには、ドキュメントのフィールドとしてproducerIdも追加し、インデックスを作成する必要があると考えています。
ここでの私の質問が実際に何であるかを明確にするために、私がこの問題について正しく考えているかどうか、またはこれにアプローチするための明らかにより良い方法があるかどうかを知りたいです。
ありがとう