![](https://habrastorage.org/files/110/214/689/1102146896034db380fc18a46cc856e0.jpg)
CouldBoost.ioプロジェクトの開発者であり従業員であるNawaz Dhandalaは、MongoDBを使用しない場合がある理由について資料を書きました。 私たちLaterでは、Hydraの通信事業者向けの課金を開発しており、長年にわたってこのDBMSと連携してきたため、この問題に関する意見を提出することにしました。
Dandalaは多くのDBMS(SQLとNoSQLの両方)で作業したことをすぐに規定し、MongoDBは優れたツールであると考えていますが、その使用が不適切なシナリオがあります。
MongoDBなどのドキュメント指向DBMSは、「コレクション」にグループ化されたJSONデータを保存する優れた仕事をします。 この形式では、任意のJSONドキュメントを保存し、便利にコレクションに分類できます。 MongoDBに含まれるJSONドキュメントは、バイナリJSONまたはBSONと呼ばれ、この形式の他のドキュメントと同様に、構造化されていません。 したがって、従来のDBMSとは異なり、あらゆる種類のデータをコレクションに格納でき、この柔軟性はデータベースの水平スケーラビリティと組み合わされます。 この機会は多くの開発者に好まれていますが、「すべてがそれほど単純ではない」。
MongoDBが非常にクールな場合、なぜ誰もが常にそれを使用しないのですか?
DBMSの選択は、作成するアプリケーションの種類によって異なります。 つまり、データベースは開発者によって選択されるのではなく、製品自体によって選択されるため、Dandalaは確信しています。 彼はこの論文を確認する例を挙げています。
ドキュメントを操作することをコンセプトとするアプリケーションを作成する場合、MongoDBが適しています。 このタイプのアプリケーションは、たとえば、各ブログ作成者が複数のブログを持つことができ、各ブログに多くのコメントが含まれるブログプラットフォームエンジンに起因します。 このようなアプリケーションを提供するためのデータベースは簡単に拡張できる必要があり、MongoDBはこれで問題ありません。
ただし、MongoDBにはドキュメントと「コレクション」の間のリンクがないことに注意する必要があります(これは、 データベースリファレンス -DBMSのリンクによって部分的に補正されますが、これで問題が完全に解決されるわけではありません)。 その結果、データベース内の他の情報とはまったく関係のない特定のデータセットが存在し、さまざまなドキュメントのデータを結合する方法がない状況が発生します。 SQLシステムでは、これは基本的なタスクです。
ここで別の質問が発生します-MongoDBに2つのテーブルを結合するための接続と可能性がない場合、なぜそれを使用するのですか? 答えは、このDBMSは非常にスケーラブルであり、従来のSQLシステムよりもはるかに高速に読み取りおよび書き込みを行うためです。MongoDBは、依存関係のあるデータをほとんど使用せず、データベースのスケーラビリティを必要とするアプリケーションに最適です。
多くの開発者は、MongoDBを使用して関連データを保存し、コードに手動結合を実装します。これは、「単一レベル」のマージスクリプトまたは少数のリンクで十分です。 つまり、この方法は普遍的とはほど遠いものです。
では、どのDBMSを選択するのでしょうか?
膨大な数の異なるDBMSがあり、それぞれが開発者がアプリケーションに対して行う特定の要件セットに対応しています。
- ドキュメント指向DBMS(MongoDBなど) :上記のように、ドキュメント指向DBMSは、JSONドキュメントを「コレクション」に保存し、必要なフィールドでクエリを実行するために使用されます。 このデータベースを使用して、あまり多くのリンクを含まないアプリケーションを作成できます。 このようなアプリケーションの良い例は、ブログプラットフォームのエンジンや製品カタログのストレージです。
- グラフDBMS(Neo4jなど) :グラフDBMSは、ノードがサブジェクトで、顔がリンクであるサブジェクト間のストレージに使用されます。 たとえば、開発者がソーシャルネットワークを作成し、あるユーザーが別のユーザーをサブスクライブする場合、ユーザーはノードであり、「サブスクリプション」は接続です。 そのようなDBMSは、リンクの深さが100レベル以上であっても、リンクを作成する優れた仕事をします。 このツールは非常に効果的であるため、eコマース詐欺も検出できます。
- キャッシュ(Redisなど) :これらのDBMSは、非常に高速なデータアクセスが必要な場合に使用されます。 各ページにカテゴリがロードされるオンライン取引用のアプリケーションを作成している場合、非常にコストがかかる読み取りごとにデータベースにアクセスする代わりに、キャッシュにデータを保存できます。 迅速な読み取り/書き込み操作が可能です。 Dandalaは、頻繁に要求されるデータを処理するためのシェルとしてキャッシュを使用するDBMSを使用することをお勧めします。これにより、データベース自体に頻繁にクエリを実行する必要がなくなります。
- DBMSの検索(ElasticSearchなど) :全文データベース検索(eコマースアプリケーションでの製品の検索など)を実行する必要がある場合、ElasticSearchのような優れたDBMSをお勧めします。 このシステムは、大量のデータで検索でき、広範な機能を備えています。たとえば、DBMSは名前付きカテゴリを検索できます。
- 文字列DBMS(Cassandraなど) :Cassandra DBMSは、シリアルデータ、ログ、または一部のセンサーなどによって自動的に生成できる大量の情報を格納するために使用されます。 開発者がDBMSを使用して大量のデータを書き込み、同時に読み取りアクセスがはるかに少なくなり、データに接続と関連付けがないことが計画されている場合は、Cassandraが適切な選択肢になると確信しています。
データベースの組み合わせを使用する
![](https://habrastorage.org/files/4a8/6e0/3af/4a86e03af20a433fb38c10de50651f08.jpg)
いくつかの異なるDBMSを一度に使用する必要がある場合があります。
たとえば、アプリケーションに検索機能がある場合、ElasticSearchを使用して実装でき、MongoDBはリンクなしでデータを保存するのに適しています。 「モノのインターネット」の分野でのプロジェクトについて話している場合、あらゆる種類のデバイスとセンサーが膨大な量のデータを生成するため、Cassandraを使用することは非常に合理的です。
複数のDBMSを使用して1つのアプリケーションで動作する原理は、「ポリグロット永続性」と呼ばれます。 この記事では、このアプローチの長所と短所について読むことができます。
私たちの経験
当社のHydra課金システムは、リレーショナルDBMSを使用してプライマリデータを記録し、財務情報を保存します。 これらの目的に最適です。 ただし、RADIUSサーバーなどの一部のHydraモジュールは、高負荷で動作し、1秒あたり数千の要求を受信できますが、要求の処理時間には厳しい制限があります。 さらに、スタンドアロンRADIUSサーバーのデータベースでは、データはAVP(属性/値のペア)のセットとして保存されます。 このようなシナリオでは、リレーショナルDBMSは最適なソリューションのようには見えません。ここで、MongoDBは、任意の構造のドキュメントの保存、回答の高速配信、および水平方向のスケーラビリティによって救いに来ます。
過去5年間に100を超えるHydraのインストールを実行した場合、Mongoに深刻な問題は見つかりませんでした。 しかし、まだいくつかのニュアンスがあります。 まず、データベースサーバーの突然のシャットダウン後、ログのおかげで復元されますが、ゆっくりと発生します。 幸いなことに、これが必要になることはまれです。 第二に、データベースのサイズが小さくても、めったに使用されないデータがディスクにフラッシュされ、リクエストがまだ到着すると、それを取得するのに長い時間がかかります。 その結果、クエリ実行の時間制限に違反します。
これはすべて、Mangoでデフォルトで使用されるMMAPv1エンジンに関連しています。 他のユーザー(WiredTigerおよびInMemory)で実験したことはありません-問題はそれほど深刻ではありません。