あなたはオープンソースソフトウェアにあまりにも多くを求めています。
エンタープライズクラスのソフトウェアの予算に数十万ドルある場合は、いくつかの解決策があります。箱から出して欲しいものを何もするつもりはありませんが、あなたが探しているものに近い製品を持っている会社があります。
「高速(その上でクエリを実行できるようになります)」
Key-Valueストアがある場合は、すべてが非常に高速である必要があります。ただし、問題は、Key-Valueストアの上に構築されたオントロジーまたはデータスキーマがないと、クエリごとにデータベース全体を調べてしまうことです。保存するデータの「タイプ」ごとにキーを含むインデックスが必要です。
この場合、通常、最大15,000台のマシンすべてに対して並行してクエリを実行できます。ボトルネックは、安価なハードドライブが1秒あたり50シークで上限に達することです。データセットがRAMに収まる場合、パフォーマンスは非常に高くなります。ただし、キーがRAMに保存されているが、値を保存するのに十分なRAMがない場合、システムはほとんどすべてのキー値ルックアップでディスクに移動します。キーはそれぞれ、ドライブ上のランダムな位置に配置されています。
これにより、サーバーごとに1秒あたり50のKey-Valueルックアップに制限されます。キーと値のペアがRAMに保存されている場合、コモディティハードウェア(Redisなど)でサーバーごとに1秒あたり100kの操作が行われることは珍しくありません。
ただし、シリアルディスクの読み取りパフォーマンスは非常に高くなります。シリアル読み取りで50MB/ s(800 Mb / s)のシークドライブがあります。したがって、ディスクに値を格納する場合は、ディスクから読み取る必要のある値をシリアルに読み取ることができるようにストレージを構成する必要があります。
それは問題。キーと値のペアを完全にRAM(またはSSDドライブ上の値を持つRAMのキー)に格納するか、あるタイプのスキーマまたはタイプシステムをその上に定義しない限り、バニラキー値ストアで良好なパフォーマンスを得ることができません。キーを押してから、ディスク上のデータをクラスター化して、特定のタイプのすべてのキーをシリアルディスク読み取りで簡単に取得できるようにします。
キーに複数のタイプがある場合(たとえば、データベースにデータ型の継承関係がある場合)、キーは複数のインデックステーブルの要素になります。この場合、ディスクからシリアルに読み取れるように値を構造化するために、時空間のトレードオフを行う必要があります。これには、キーの値の冗長コピーを保存する必要があります。
特にクエリを実行する場合は、Key-Valueストアよりも少し高度なものが必要になります。ただし、大きなファイルを保存する問題は問題ではありません。システムが最大50メガをキーイングできるふりをします。次に、1ギガのファイルを50メガのセグメントに分割し、各セグメントの値にキーを関連付けます。単純なサーバーを使用すると、必要なファイルの部分をKey-Valueルックアップ操作に変換するのは簡単です。
冗長性を実現する問題はより困難です。サーバーのキー値テーブルを「ファウンテンコード」または「パーツファイル」するのは非常に簡単なので、特定のサーバーが停止した場合に、サーバーのデータをワイヤ速度(1 Gb / s)でスタンバイサーバーに再構築できます。通常、サーバーが10秒間応答しない場合にトリガーされる「ハートビート」システムを使用して、サーバーの停止を検出できます。パーツファイルでエンコードされたKey-Valueテーブルに対してKey-Valueルックアップを行うことも可能ですが、それは非効率的ですが、サーバー障害が発生した場合のバックアップを提供します。より大きな問題は、バックアップを最新の状態に保つことはほとんど不可能であり、データは3分前のものである可能性があります。大量の書き込みを行う場合、バックアップ機能によってパフォーマンスのオーバーヘッドが発生します。
私は障害モードでデータベースの整合性と整合性制約を維持する専門家ではないため、この要件によってどのような問題が発生するかわかりません。これについて心配する必要がない場合は、システムの設計とその要件が大幅に簡素化されます。
高速(その上でクエリを実行できるようになります)
まず、データベースがこれほど大きい場合は、結合やn * log(n)よりも高速にスケーリングする操作を忘れてください。通常実装されている機能を結合で置き換えるためにできることは2つあります。結合を行う必要がないようにデータを構造化するか、実行しているクエリを「プリコンパイル」して時間と空間のトレードオフを行い、結合を事前に計算して、事前にルックアップ用に保存することができます。 。
セマンティックWebデータベースの場合、適度なサイズのデータセットでも適切なパフォーマンスを実現するために、クエリを事前にコンパイルし、時間と空間のトレードオフを行う人々が見られると思います。これは、アプリケーションプログラマーの努力なしに、データベースバックエンドによって自動的かつ透過的に実行できると思います。ただし、リレーショナルデータベースにこれらの手法を実装しているエンタープライズデータベースはまだ始まったばかりです。私の知る限り、オープンソース製品はこれを実行しません。水平方向にスケーラブルなデータベースのリンクトデータに対してこれを実行しようとしている人がいるとしたら、私は驚きます。
これらのタイプのシステムでは、追加のRAMまたはストレージスペースがある場合、キー値ストアに冗長性を追加するのではなく、パフォーマンス上の理由から、一般的なサブクエリの結果を事前に計算して保存するのが最適です。結果を事前に計算し、クエリ対象のキーで並べ替えて、n ^ 2結合をlog(n)ルックアップに変換します。n * log(n)よりもスケーリングが悪いクエリまたはサブクエリは、結果を実行してKey-Valueストアにキャッシュする必要があるものです。
多数の書き込みを実行している場合、キャッシュされたサブクエリは、処理できるよりも早く無効になり、パフォーマンス上の利点はありません。キャッシュされたサブクエリのキャッシュ無効化に対処することは、もう1つの手に負えない問題です。解決策は可能だと思いますが、見たことがありません。
地獄へようこそ。このようなシステムをさらに20年間無料で入手できると期待すべきではありません。
これまでのところ、100ポイントの賞金を提供した後でも、質問に答えられなかったとしても、私が述べた基準を満たすデータベースまたはキーバリューストアはないようです。
あなたは奇跡を求めています。オープンソースの奇跡のデータベースができるまで20年待ちます。そうしないと、アプリケーションのニーズに合わせてカスタマイズされたソリューションにお金を払う必要があります。