次のシナリオがあります。
約 7000 万の機器が 3 ~ 5 分ごとにサーバーに信号を送信し、ID、ステータス (オンラインまたはオフライン)、IP、場所 (緯度と経度)、親ノード、およびその他の情報を送信します。
他の情報は標準形式ではない可能性があります (したがって、スキーマはありません) が、クエリを実行する必要があります。
機器は、その過程で信号を送信せずに、しばらくの間 (または永久に) 消える可能性があります。したがって、機器が過去 X 日間信号を送信していない場合、その機器を「忘れる」方法が必要です。また、新しい機器がいつでもオンラインになる可能性があります。
このすべてのデータを照会する必要があります。特定の地域または IP 範囲でオフラインになっている機器の数を知ることと同様です。同時に実行されるクエリは多くありません。
一部のクエリは、データベースの更新と同時に高速 (クエリあたり 3 分未満) で実行する必要があります。そのため、主要な属性 (id、ステータス、IP、場所、および親ノード) のインデックスが必要です。クエリ結果は 100% 正確である必要はありません。クエリ結果に表示されるまでに時間がかかりすぎない限り (平均で 20 分以上)、結果整合性は問題ありません。
しつこさは全くいらない、力が抜けたら全部失ってもいい。
これらすべてを考慮して、MapReduceとJavascriptの経験があるため、おそらくMongoDBまたはCouchDBのnoSQLアプローチを使用することを考えましたが、どちらが自分の問題に適しているかわかりません(私はCouchDBに引き寄せられています)、またはそれらがまったく適しているかどうかはわかりませんこの膨大なワークロードを処理するために。ディスクへの永続性は必要ないので、実際に「従来の」データベースが必要かどうかさえわかりませんが (メイン メモリのアプローチの方がよいのではないでしょうか?)、カスタム クエリを簡単に作成する方法が必要です。
私が検出した主な問題は次のとおりです。
大量のタプルを非常に高速に挿入/更新する必要があり、受信したシグナルが既にデータベースにあるかどうかを事前に知りません。ほとんどすべてのシグナルは前回と同じ状態になるので、id でクエリを実行して、タプルが更新された場合は何もしないかどうかを確認しますか?
オフライン機器を忘れる。期限切れのタプルを削除する夜間に実行されるバッチ ジョブは、この問題を解決します。
同時に実行されるクエリは多くありませんが、高速に実行する必要があります。したがって、クラスターの複数のノードで単一のクエリを実行するクラスターが必要だと思います (CouchDB MapReduce はワークロードをクラスターの複数のノードに分割しますか?)。クラスターが必要かどうかはよくわかりませんが、より高価な 1 台のマシンですべての負荷を処理できますか?
これまで noSQL システムを使用したことはありませんが、このテーマに関する理論的な知識は持っています。