1. ホーム
  2. MongoDB

MongoDB総合まとめ

2022-02-11 23:57:30

原文: http://blog.csdn.net/jakenson/article/details/7060431

MongoDB 内部構造 "MongoDB決定版ガイド

MongoDBの公式ドキュメントは基本的にやり方は紹介されていますが、どのように動作したかはほとんど紹介されておらず、MongoDB TheDefinitive Guideを買ったばかりでまだ読む機会がありません。一見の価値ありです。

今日、MongoDB The Definitive Guideの電子版をダウンロードして立ち読みしてみましたが、かなり参考になりますね。公式ドキュメントの補足として、実用的なアプリケーションについて書かれています。公式ドキュメントと同様、MongoDBの内部についてはほとんど書かれておらず、付録の1セクションで扱っているのみです。

ほとんどのMongoDBユーザーにとって、MongoDBは大きなブラックボックスですが、その内部をある程度理解することができれば、MongoDBをより理解し、使うことができるようになります。

BSON

MongoDB では、ドキュメントとはデータを抽象化したもので、クライアント側とサーバー側のやりとりで使われます。すべてのクライアント (すべての言語のドライバ) がこの抽象化されたデータを使いますが、その形式は BSON (Binary JSON ) と呼ばれるものです。

MongoDBはBSONを使うことができ、データの保存先としてBSONをディスクに保存することができます。

Client 側がドキュメントに書き込んだり、クエリを使ったりしたい場合、ドキュメントを BSON フォーマットでエンコードして Server 側に送信する必要があります。同様に、サーバー側からの返送結果は、BSONフォーマットでエンコードされ、クライアント側に返されます。

BSONフォーマットは、以下の3つの目的で使用されます。

効率化

BSONは効率性を重視した設計になっており、使用するスペースが非常に少ないのが特徴です。最悪のシナリオでも、BSONフォーマットはJSONフォーマットよりも、ベストケースの保存に効率的です。

輸送性

BSONでは、データの転送を容易にするために、余分なスペースを犠牲にしている場合があります。たとえば、文字列転送のプレフィックスは、文字列の末尾にあるエンドマーカーではなく、文字列の長さを識別するものです。このような転送形式は、MongoDB が転送されたデータを変更するのを容易にします。

パフォーマンス

最後に、BSONフォーマットは、エンコードとデコードが非常に高速です。また、C言語スタイルのデータ表現を使っているので、様々な言語で効率的に使用することができます。

BSONについては、以下をご参照ください。 http://www.bsonspec.org .

プロトコルへの書き込み

Client側は、軽量なTCP/IP書き込みプロトコルを使ってServer側にアクセスする。このプロトコルは MongoDB ウィキ が詳しく説明されていますが、実際にはBSONデータの上に単純なラッピングを施しただけのレイヤーです。例えば、データを書き込むコマンドは、20バイトのメッセージヘッダ(メッセージの長さと書き込みコマンドの識別子で構成)、書き込む必要のあるコレクションの名前、書き込む必要のあるデータを含んでいます。

データファイル

MongoDB の data フォルダ (デフォルトのパスは /data/db) には、データベースを構成するすべてのファイルが格納されています。各データベースには .ns ファイルといくつかのデータファイルが含まれ、データファイルはデータ量が増えるにつれて大きくなります。つまり、fooという名前のデータベースがあれば、fooデータベースを構成するファイルは、foo.ns、foo.0、foo.1、foo.2、...というように構成されることになるのです。

このデザインは、小規模なデータベースが無駄に容量を消費するのを防ぐと同時に、大規模なデータベースが適切な量の容量を使用できるようにするために役立ちます。

MongoDB は一貫した書き込みパフォーマンスを確保するために preallocation を使用します (これは -noprealloc でオフにすることができます)。事前割り当てはバックグラウンドで行われ、事前割り当ての各ファイルはゼロでパッドされます。これによって MongoDB は常に余分なスペースを確保してデータファイルを解放することができ、過剰なデータ増加によるディスクスペースの確保で発生するブロックを回避できます。

名前空間とディスク領域

すべてのデータベースは複数の名前空間からなり、それぞれが適切な種類のデータを格納する。データベース内の各コレクションには、それぞれ対応する名前空間があり、インデックス・ファイルにも名前空間があります。すべてのネームスペースのメタデータは、.ns ファイルに格納されます。

ネームスペース内のデータは、ディスク上の複数のセクタに分割され、これをディスクセクタと呼ぶ。下図では,データベースfooには3つのデータファイルがあり,3つ目のデータファイルはあらかじめ確保された空のファイルである.最初の2つのデータファイルは、異なる名前空間に対応するディスクセクタに分割される。

上図は、ネームスペースとディスク領域に関連する特性を示したものである。各ネームスペースには複数の異なるディスク・セクタを含めることができ、これらは連続したものではありません。データファイルが大きくなるのと同じように、各ネームスペースに対応するディスクのサイズも、割り当ての回数に応じて大きくなる。これは、ネームスペース内の無駄なスペースと、特定のネームスペース内のデータの連続性のバランスをとるためである。上の図では、もうひとつ注意すべき名前空間があります。これは、もう使用されていないディスク(削除されたコレクションまたはインデックス)を追跡するために使用されます。ネームスペースが新しいディスクを割り当てる必要があるときはいつでも、まず $freelist に使用する適切なサイズのディスクがあるかどうかを確認します。

メモリマップトストレージエンジン

現在、MongoDBがサポートしているストレージエンジンは、メモリマップドエンジンです。MongoDB が起動すると、すべてのデータファイルをメモリにマップし、ディスク操作はすべてオペレーティングシステムがホストします。このストレージエンジンには、いくつかの特徴があります。

* MongoDBのメモリ管理に関するコードは非常に無駄がありません。結局のところ、関連する作業はすでにオペレーティングシステムによってホストされているのです。

* MongoDBサーバーが使用する仮想メモリは巨大になり、データファイル全体のサイズを超えることになります。心配しないでください、オペレーティングシステムがすべて処理します。

* MongoDBはデータがディスクに書き込まれる順番を制御できないので、結果的にwriteahead logging機能を実装できないことになります。そのため、MongoDBが耐久性機能を提供したい場合(この機能は、Cassandraに関する拙稿の http://www.cnblogs.com/gpcuster/tag/Cassandra/ のように、別のストレージエンジンを実装する必要があります。

* 32ビットシステムのMongoDBサーバーは、1つのMongodインスタンスにつき2Gのデータファイルしか使用できません。これはアドレスポインタが 32 ビットしかサポートできないためです。

その他

MongoDB The Definitive Guideで紹介されているMongoDB内部は限られているので、本当に明確にしようと思ったら、それ専用の本がもう一冊必要かもしれません。例えば、内部のJSのパース、クエリーの最適化、インデックスの構築などです。興味のある方は、直接ソースコードを参照してください。

MongoDBのアーキテクチャ

現在のアーキテクチャ デュアルサーバアーキテクチャ


現在のアーキテクチャはシングルシャード+レプリカセットモデルで、デュアルサーバーはデュアルシャード+レプリカセットモデルです。同一シャード内のプライマリ、セカンダリのストレージの内容は同じである。これに対してデュアルシャードは、異なるデータを分散して保存する2つのシャードで、バックアップはシャード内部で行う。

デュアルサーバの2つのシャードには、それぞれプライマリ、セカンダリ、アービタ(アービタの目的は、プライマリがダウンした後に新しいプライマリを選出する際の投票権を持つこと、生き残っているノード数を50%以上にしないとシステムがダウンすること、投票数が同じ場合は選挙を打ち切ることのみ(投票数が同じ場合はバランスを壊す)、データを保存・読み出すことではない)が含まれています。

同一シャード内ではプライマリーしか書き込みに使用できないため、セカンダリーはプライマリーノードのバックアップと読み出しにのみ使用し、プライマリーがダウンした場合に引き継ぎを行います。したがって、デュアルシャードモードでは、2台のサーバーにそれぞれプライマリを搭載し、同じシャードのアービタはセカンダリと同じサーバーに置く必要があります。これにより、プライマリがダウンした場合でも、両方のサーバーで読み取りと書き込みの操作を行い、選択されたセカンダリを成功させ続けることができます。

スケーリング時には、新しいシャードをクラスタに追加して、古いシャードとのバランスをとることができます。

MongoDBの特徴

MongoDBは、コレクション指向のスキーマフリーなドキュメントベースのデータベースである。

コレクション指向 つまり、データはアグリゲーションと呼ばれるコレクションにグループ化される。各集約はデータベース内でユニークな名前を持ち、無制限の数のドキュメントを含むことができる。集約はRDBMSのテーブルと同義であるが、集約にはスキーマの定義が必要ない。

スキーマの自由度 つまり、データベースは、アグリゲートに預ける文書に関する構造情報を知る必要がない。実際、異なる構造を持つドキュメントを同じアグリゲートに格納することができます。

文書タイプ ここでキーは文字列で、値は配列や文書など、データ型に含まれる任意の型にすることができる。このデータ形式を[BSON]", すなわちBinary Serialized dOcument Notation."と呼んでいます。

u ドキュメント指向のストレージ。(JSONのようなデータモデルはシンプルで強力)。

u 効率的な従来型ストレージ:バイナリデータやラージオブジェクト(写真やビデオなど)をサポートします。

u レプリケーションと自動フェイルオーバー。Mongo Databaseはサーバー間のデータレプリケーション、マスター・スレーブモード、サーバー間の相互レプリケーションをサポートします。

u クラウドレベルのスケーラビリティを実現するオートシャーディング(初期アルファ版)。自動シャーディングは、動的にマシンを追加できる水平データベースクラスタリングをサポートします。

u ダイナミッククエリ。リッチなクエリ表現をサポートしています。クエリーコマンドは、JSON 形式のマークアップを使用して、ドキュメントに埋め込まれたオブジェクトや配列を簡単にクエリーできます。

Mongoのクエリオプティマイザーはクエリ式を解析し、効率的なクエリプランを生成します。 u 完全なインデックス作成サポート:ドキュメントに埋め込まれたオブジェクトや配列も含みます。

u RUBY、PYTHON、JAVA、C++、PHP などに対応。

u コレクション指向のストレージ、オブジェクト型のデータの保存が容易:コレクションに保存されたドキュメントは、キーと値のペアで保存されます。キーは文書を文字列型として一意に識別するために使用され、値は様々な複合文書型にすることができます。

u * スキーマフリー:mongodbデータベースに格納された文書で、その構造的な定義を知る必要がない。

u * 内部オブジェクトを含む、完全なインデックスをサポートします。

u * レプリケーションとフェイルバックをサポートします。

u *自動シャーディング。自動シャーディング機能は、動的にマシンを追加できる水平データベースクラスタリングをサポートします。

u クエリモニタリング。Mongoにはデータベース操作のパフォーマンスを分析するためのモニタリングツールがあります。

MongoDBの特徴

       クエリ クエリオブジェクトまたはSQLライクなステートメントに基づいてドキュメントを検索します。クエリの結果は、ソートしたり、サイズを制限して返したり、結果セットの一部をスキップしたり、ドキュメントの一部を返したりすることができます。

       挿入と更新:新しい文書を挿入し、既存の文書を更新します。

       インデックス管理: 文書の1つまたは複数のキー(サブストラクチャーを含む)に対するインデックスの作成、インデックスの削除、など。

共通コマンド。MongoDBのすべての操作はソケット化されたDBコマンドで行うことができます。

MongoDBの制限と欠点

この記事は、QuoraのQ&Aをまとめたもので、主なものを挙げています。 モンゴルDB この記事はQuoraのQ&Aをまとめたもので、MongoDBの制限やうまくできないことをリストアップしています。MongoDBがそもそもやりたくなかった部分や、MongoDBがやりたかったけどうまくいかなかった部分などが含まれています。

  • 32ビットシステムでは、2.5Gを超えるデータはサポートされていません。詳細は、以下を参照してください。 こちら
  • 単一文書サイズ制限4M/16M(バージョン1.8以降は16Mまで)。
  • ロックの粒度が粗すぎる。MongoDBはグローバルな読み取り/書き込みロックを使用しています。 こちら
  • 結合操作やトランザクションの仕組みはサポートされておらず、これは本当にMongoDB以外の領域で行うことである
  • 少なくともホットデータ(インデックス、データ、その他のシステムオーバーヘッド)がメモリに収まるようにするために、大きなメモリが必要です。
  • ユーザーのパーミッションが弱い、これはMongoDBが公式に推奨していることで、マシンを安全なイントラネット環境にデプロイしてパーミッションを使わないようにする、で詳しく説明されています。 こちら
  • MapReduceは単一インスタンスでは並列化できず、Auto-Shardingを使用することで初めて並列化することができます。これはJSエンジンの制限に起因するものです
  • MapReduceの結果を、シャーディングされているCollectionに書き込むことはできないが、バージョン2.0では問題ない 問題 によって完全に解決されるわけではなさそうです。
  • 配列型のデータ操作には十分なリッチさがない
  • 自動シャーディングにはまだ多くの問題があり、いわゆる水平方向のスケーリングはあまり理想的ではない

適用範囲

u リアルタイムにデータを保存するアプリケーションに必要なレプリケーションと高いスケーラビリティを備えたリアルタイムのインサート、アップデート、クエリに適しています。

u 情報インフラの永続的なキャッシュ層として適している。

u 数十台、数百台のサーバで構成されるデータベースに適している。MongoにはすでにMapReduceエンジンのサポートが組み込まれているから。

u Mongoの BSON データフォーマットは、文書化されたフォーマットの保存とクエリに最適です。

Webデータ。Mongoはリアルタイムの挿入、更新、クエリに最適で、リアルタイムのWebデータ保存に必要なレプリケーションと高いスケーラビリティを備えています。

u ◆キャッシュ:Mongoはその高いパフォーマンスから、情報インフラのキャッシュ層としても適しています。システムを再起動すると、Mongo が構築した持続的なキャッシュ層が、下位のデータソースに過負荷をかけるのを防ぎます。

u ◆大容量、低価値のデータ。従来のリレーショナル・データベースを用いてデータを保存するにはコストがかかる場合があり、それまではプログラマーが従来のファイルをストレージとして選択するケースが多く見られます。

u ◆拡張性の高いシナリオ。Mongoは数十台から数百台のサーバーで構成されるデータベースに適しています。MongoのロードマップにはすでにMapReduceエンジンのビルトインサポートが含まれています。

u ◆オブジェクトやJSONデータの保存に。MongoのBSONデータ形式は、ドキュメント形式の保存とクエリに最適です。

MongoDBの除外項目

- トランザクションの多いシステム。

- 従来のビジネス・インテリジェンス・アプリケーション。

- 複雑なSQLクエリに対応するレベル。

- 高度なトランザクションシステム:銀行や会計システムなど。多数のアトミックで複雑なトランザクションを必要とするアプリケーションには、やはり従来のリレーショナル・データベースが適している。

- 従来のビジネス・インテリジェンス・アプリケーション。問題に特化した BI データベースは、高度に最適化されたクエリを生成するのに有効であろう。このようなアプリケーションでは、データウェアハウスがより適切な選択となる場合があります。

- SQLが必要な問題

u   

要項

mysqldのように、mongodサービスは複数のデータベースを持つことができ、それぞれのデータベースは複数のテーブルを持つことができます。ここでは、テーブルはコレクションと呼ばれ、それぞれのコレクションは複数のドキュメントを保持でき、それぞれがハードディスクにBSON(バイナリjson)として保存されます。リレーショナルデータベースとは異なり、一つの文書を保存単位としているので、他の文書に影響を与えることなく、文書や文書群にフィールドを追加したり削除したりすることができ、これをスキーマフリーと呼び、これが文書ベースデータベースの最大の特徴である。一般的なKey-Valueデータベースとは異なり、値の中に構造情報が格納されているので、リレーショナルデータベースのように特定のフィールドに対して読み書きや統計などの操作を行うことができる。キーバリューデータベースの利便性と効率性、リレーショナルデータベースのパワーを併せ持ったデータベースと言えるでしょう。

インデックス

リレーショナルデータベースと同じように、mongodbはフィールドにインデックスを作ることができ、結合インデックス、ユニークインデックスを作ることができ、インデックスを削除することができます。私のアドバイスは、もしあなたがドキュメントをオブジェクトとして考えることができるなら、オンラインアプリケーションでは、通常、オブジェクトIDにインデックスを作り、IDに基づいてmemcacheにいくつかのデータを置くだけでいいということです。バックグラウンドの分析ニーズであれば、レスポンス要件は高くないので、テーブルを直接掃引してもそれほど時間がかからない場合でも、インデックスのないフィールドにクエリを実行します。どうしても我慢できないなら、別のインデックスを作ればいい。

デフォルトでは、各テーブルはユニークなインデックスを持っています。idです。データを挿入する際に_idが指定されない場合、サービスは自動的に_idを生成します。

キャップドコレクション

キャップド・コレクションは特別な種類のテーブルで、ビルド・コマンドは

db.createCollection("mycoll",{capped:true, size:100000})

テーブル構築の最初に一定のスペースサイズを指定できるようにすると、次の挿入操作では、このあらかじめ確保されたスペースファイルに順番にデータを連続的にAPPENDし、スペースサイズを超えた場合は、ファイルヘッダに戻り、元のデータを上書きして挿入を続ける。この構造により、挿入と問い合わせの効率が確保され、個々のレコードの削除は許されず、更新されたものも元のレコードのサイズを越えてはいけないという制約がある。このようなテーブルは非常に効率的で、Webサイトにログインしたユーザーのセッション情報や、一部のプログラムの監視ログなど、一定期間が経過すると上書きされてしまうデータの一時保存に適している。

レプリケーションとフラグメンテーション

mongodbのレプリケーションアーキテクチャはmysqlと同様にマスタースレーブ構成とマスターマスター構成、そしてレプリカペア構成があり、通常はマスタースレーブと同様に動作しますが、マスターがダウンした場合、アプリケーションは自動的にスレーブに接続されます。レプリケーションを行うのは簡単で、私自身もマスタースレーブ構成を使っていますが、一方のサービスの起動時に-masterパラメータを、もう一方のサービスには-slaveと-sourceパラメータを追加するだけで同期を行うことができます。

シャーディングは大きな頭痛の種です。データ量をシャーディングする必要があり、mysqlの下でのシャーディングはまさに無数のDBAの悪夢となりました。mongodbの下では、Key-Valueデータベースのようなドキュメントデータベースの容易な配布が活きており、シャーディングサービスの構築、ノードの追加、削除が非常に簡単に行えます。しかし、この分野でmongodbは十分に成熟していない、今だけアルファ2バージョン(mongodbのv1.1)にスライスの仕事は、それが解決するために多くの問題があると推定されているので、我々は唯一の楽しみにして、あまり言わないことができる。

パフォーマンス

私の場合、ドキュメントオブジェクトが1000万個、データ量が10G近くありますが、インデックス付きのIDに対するクエリはmysqlより遅くはなく、インデックスなしのフィールドに対するクエリは軒並み良好です。mysqlはデータ量の多い任意のフィールドに対するクエリにはあまり向いておらず、mongodbのクエリ性能には本当に驚かされました。書き込み性能も非常に満足のいくものです。mongodbは以前試したcouchdbよりもずっと速く、10分もかからずに解決することができます。余談ですが、mongodbは観測中にCPUキラーになるには程遠いです。

グリッドエフエス

gridfsはmongodbのファイルシステムのような面白いもので、大きなファイルスペースを使って小さなファイルを大量に保存することができます。これは特に、Web 2.0 サイトでよくある大量の小さなファイル(大量のユーザーアバターなど)を保存するのに有効です。また、基本的には通常のファイルシステムと同様であり、使い勝手が良い。

適切なデータベースで適切なことをする

mongodbのドキュメントに書かれているユーザーケースは、リアルタイム分析、ロギング、全文検索などで、中国ではmongodbを使ってWebログの保存や分析をしている人もいますが、ある程度の規模のWebログを扱うにはmongodbは向いていないと思います、主な理由は容量を取りすぎることです、元の1Gのログデータは数Gとして保存できます このままでは数日分のログをハードディスクでは保存できないのではと言われています。一方、データ量についてはシャーディングを考慮する必要がありますが、mongodbのシャーディングは今のところまだあまり成熟していません。ログは更新できないので、APPENDすればよいという性質があり、また、ログに対する操作は1つか2つのカラムだけに集中することが多いので、ログ分析に最も適したデータベースはカラムストレージのデータベース、特にinfobrightのようにデータウェアハウス用に設計されたものです。

mongodbはトランザクションをサポートしていないので、トランザクションの要件が厳しいシステム(銀行システムなど)は絶対に使用しないでください。

モンゴルDB 分散レプリケーション

I. マスター・スレーブ構成 (マスタースレーブ)
    マスタースレーブデータベースは、マスターとスレーブの2つのデータベースノードが必要です(2つの別々のサーバーである必要はなく、-dbpathパラメータでデータベースディレクトリを指定することができます)。スレーブノードが複数のマスターノードを持つことも可能で、その場合は ローカル.ソース は複数のコンフィギュレーションメッセージを持つことになります。サーバは同時にマスターにもスレーブにもなることができます。スレーブノードがマスターノードと同期していない場合、例えばスレーブノードのデータ更新がマスターノードから大きく遅れていたり、スレーブノードが停止した後に再起動したがマスターノードの関連するデータ更新ログが利用できない場合などです。この場合、レプリケーション操作は終了し、デフォルトでレプリケーション操作を再開する必要があるかどうか、管理者が介入する必要があります。管理者は { <未定義 再同期:1 } コマンド オプションのコマンドライン引数でレプリケーション操作を再開します。 --autoresync は、同期外れが発生してから10秒後に、スレーブノードが自動的にレプリケーションを再開するようにします。もし パラメータを指定すると、スレーブノードによる10分以内のデータの自動再同期は1回のみ行われます。
--oplogSize コマンドラインパラメータ (と同じ)。 --マスタ とは併用されます。 ) は、スレーブノードが利用できるアップデートを保存するために使用するディスク容量 (M単位) を設定します。このパラメータを指定しない場合、デフォルトのサイズは現在利用可能なディスク容量の5%です(64ビットマシンの場合は最低1G、32ビットマシンの場合は50M)。

II. 相互のマスター・スレーブ( レプリカペア )
データベースは、ある時点で自動的に主従関係を調整する。最初のうちは、データベースがどちらから、どちらがマスターかを判断し、マスターサーバーに負荷がかかると、もう一方が自動的にマスターサーバーになります。
リモートサーバー グループ内の他のサーバホストには、:port を付けてポートを指定します。
アービターサーバー  arbiterserverはarbiterのホストで、ポートを指定することも可能です。アービターはある時点でのデータベースのマスター・スレーブ関係を決定するのに使われるmongodbサーバーである。同じサーバー群が同じスイッチ上や同じec2アベイラビリティゾーンにある場合は、アービトレーションを使う必要はない。同じグループのサーバーが互いに通信できない場合、サードパーティーのマシンで仲裁を使用して、quot;grab seven"方式でマスターサーバーを効果的にノックアウトすることもできますし、仲裁を使用せずに、すべてのサーバーがマスター状態にあると仮定して、コマンドで現在どのデータベースがマスターであるかを手動で検出することもできます。
$ . /mongo 
> db.$cmd.findOne({ismaster:1});
{ "ismaster" : 0.0 , "remote" : "192.168.58.1:30001" , "ok" : 1.0 } 。 
一貫性がある。フェイルオーバーメカニズムは、グループ内のデータベースのデータの最終的な一貫性を保証することしかできません。マシンLがプライマリーサーバーで、その後ハングアップした場合、そのマシンに起こった最後の数秒間の操作に関する情報はマシンRに届かず、マシンLが回復するまでマシンRはそれらの操作を実行できない。
セキュリティ:マスター・スレーブと同じ操作。
データベースサーバーの交換。サーバーに障害が発生した場合、オンラインで自動的に復旧させることができます。しかし、完全にハングアップした場合は交換する必要があり、交換したマシンにそもそもデータがない場合はどうなるのでしょうか。ここでは、サーバー群のマシンを交換する方法について説明します。

MongoDBの構文と既存のリレーショナルデータベースのSQL構文との比較

MongoDB の構文 MySql の構文

db.test.find({'name':'foobar'})<==> select * from test where name='foobar'

db.test.find() <==> select *from test

db.test.find({'ID':10}).count()<==> select count(*) from test where ID=10

db.test.find().skip(10).limit(20)<==> select * from test limit 10,20

db.test.find({'ID':{$in:[25,35,45]}})<==> select * from test where ID in (25,35,45)

db.test.find().sort({'ID':-1}) <==> select * from test order by IDdesc

db.test.distinct('name',{'ID':{$lt:20}}) <==> select distinct(name) from testwhere ID<20

db.test.group({key:{'name':true},cond:{'name':'foo'},reduce:function(obj,prev){prev.msum+=obj.marks;},initial:{msum:0}}) <==> select name,sum(marks) from testgroup by name

db.test.find('this.ID<20',{name:1}) <==> select name from test whereID<20

db.test.insert({'name':'foobar','age':25})<==>insertinto test ('name','age') values('foobar',25)

db.test.remove({}) <==> testから*を削除する。

db.test.remove({'age':20}) <==> test where age=20 を削除します。

db.test.remove({'age':{$lt:20}}) <==> elete test where age<20

db.test.remove({'age':{$lte:20}}) <==> delete test where age<=20

db.test.remove({'age':{$gt:20}}) <==> delete test where age>20

db.test.remove({'age':{$gte:20}})<==> delete test where age>=20

db.test.remove({'age':{$ne:20}}) <==> delete test where age!=20

db.test.update({'name':'foobar'},{$set:{'age':36}})<==> update test set age=36 where name='foobar'(テストセット年齢36)

db.test.update({'name':'foobar'},{$inc:{'age':3}})<==> update test set age=age+3 where name='foobar'

億単位のデータ量に対するMongodbのパフォーマンステスト

Mongodbの10億データボリュームでパフォーマンステストを実施し、以下の各項目をテストしました。
(挿入はすべてシングルスレッド、読み込みはすべてマルチスレッドです。)
1) 通常の挿入性能 (挿入されるデータはそれぞれ1KB程度)
2) バッチ挿入パフォーマンス(公式C#クライアントInsertBatchを使用)、これはバッチ挿入パフォーマンスがどの程度改善されるかを測定します。
3) 安全挿入(挿入を成功させる、SafeMode.True スイッチを使用)、これは安全挿入のパフォーマンスがどの程度悪くなるかを測定するものである。
4) インデックスの後に数値カラムをクエリーし、10レコード(つまり10KB)を返したときのパフォーマンス、これはインデックスクエリーのパフォーマンスを測定します。
5) 2つのインデックス付き数値列を照会し、10レコードを返した場合の性能(各レコードは約20バイトの小さなフィールドを2つだけ返す)、これは少量のデータを返す場合の性能ともう1つのクエリー条件の影響を測定する
6) インデックスの後に数値列を問い合わせ、別のインデックスの日付フィールドでソートし(インデックスは逆順に構築され、ソートも逆順)、100レコードをスキップして10レコードを返す場合の性能、これは、性能に対するスキップおよび順序の影響を測定します。
7) 100レコード(つまり100KB)のクエリー(ソートなし、条件なし)のパフォーマンス、これは大容量データの結果をクエリーする際のパフォーマンスへの影響を測定します。
8)テストの進行に伴い、総ディスクフットプリント、インデックスディスクフットプリント、データディスクフットプリントをカウントする

モンゴDB CEO。ビッグデータ量に対応するNoSQLの実力

MongoDBを支える10gen社のCEO、Kevin Ryan Dwight Merriman氏は、"当社は3月29日に設立されましたが、シーミー市場を選択したのではなく、エンタープライズユーザー市場をゆっくりと変化させていくと考えています。今では、数ヶ月前はゼロだったMongoDB.orgのサイトが、月に3万ダウンロードされていることがわかります"。

10genのCEO、ドワイト・メリマン氏

MongoDBの名前の由来はhumongousという形容詞ですが、スケールアップして大容量のデータを素早く処理するには精度が落ちます。サンフランシスコで開催されたMondoDBカンファレンスで、Merriman氏は「データの一貫性が保証されないかもしれない証券取引などの複雑な金融取引には使用しないほうがいい」と述べています"'t'。

NoSQLデータベースは、MongoDBやCouchDBのように目的別にラベル付けされており、どちらも文書指向のデータベースですが、テキスト文書をJSON(JavaScript ObjectNotation)のような構造化データとして保存できるわけではありません。

JSONはXMLに代わるものと考えられており、XMLと同様に人間が読める軽量なテキストベースのデータ交換用規格である。JSONの単純なデータ構造はオブジェクトと呼ばれ、整数(int)、文字列(string)、配列(array)、日付(date)、オブジェクト(object)、bytearrayなど様々なデータ型を含むことができる。

ドキュメント指向データベースがリレーショナルデータベースと大きく異なる点は、ドキュメント指向データベースはデータを行単位ではなく、整理されたファイル単位で保存することです。MongoDBではドキュメントの集合をコレクションとして扱い、リレーショナルデータベースでは多数の行からなる集合をテーブルとして扱います。

しかし同時に、リレーショナルデータベースではselect、insert、update、deleteでテーブルのデータを操作し、ドキュメント指向データベースではquery、insert、update、removeで同じ意味の操作を行う点では似ています。

MongoDBではオブジェクトの最大サイズは4MBに制限されていますが、オブジェクトの数に制限はありません。MongoDBはクラスタリングによって処理の実行を高速化することができ、データベースが大きくなれば、サーバーをクラスタに追加してパフォーマンスの問題を解決することができる。

Wordnikのエンジニアリング担当副社長であるTony Tam氏は、彼の会社には500万件の文書があり、以前は約1.5TBのMySQLデータベースに保存されていたが、1ヶ月前にMongoDBに移行したと語った。 安心を得られる。

タム氏によると、MySQLデータベースでは、Wordnikプロジェクトは凸凹道で、データテーブルのフリーズが10秒を超えることもあり、これは誰もが許容できる範囲を超えていたという。私たちは、1日に約200の新しい単語を収集し、その使用法を示すために1,500の例をデータベースに追加する責任を負っており、1秒でデータベースに書き込むことを望んでいました」とタムは言います。しかし、それを保証することはできません。

Wordnikのシステムは巨大なオンライン辞書のようなもので、多くの人が同時にクエリを発行していますが、同時に更新も行っています。MongoDBを使えば、データベースの詰まりを心配することなく、高速にデータを追加し続けることができるんです」。MongoDB"のMondoDBでは、彼の会社がMySQLからMongoDBに移行するのにたった1日しかかからなかったと述べています。

拡張リーディング

Mongoは高性能なオープンソースのスキーマフリー文書ベースデータベースで、従来のリレーショナルデータベースやキー/バリューストレージ方式に代わるものとして多くの場面で利用できる。C++で開発されたMongoは次のような機能を備えている。

コレクション指向のストレージ:オブジェクトや JSON 形式のデータの保存に適しています。

動的なクエリ。Mongoは豊富なクエリ表現をサポートしています。クエリーコマンドは JSON 形式のマークアップを使い、ドキュメントに埋め込まれたオブジェクトや配列を簡単にクエリーできます。

ドキュメントに埋め込まれたオブジェクトや配列を含む完全なインデックス作成をサポートします。Mongo のクエリオプティマイザはクエリ式を解析し、効率的なクエリプランを生成します。

クエリの監視。Mongo にはデータベース操作のパフォーマンスを分析するための監視ツールが含まれています。

レプリケーションと自動フェイルオーバー。Mongoデータベースはサーバー間のデータレプリケーション、マスタースレーブモード、サーバー間のレプリケーションをサポートしています。レプリケーションの主な目的は冗長性と自動的なフェイルオーバーを提供することです。

従来のストレージを効率化。バイナリデータや写真・画像などの大きなオブジェクトに対応。

クラウドレベルのスケーラビリティをサポートする自動シャーディング(初期アルファ版)。自動シャーディング機能により、動的にマシンを追加できる水平データベースクラスタリングをサポートします。

MongoDBの第一の目標は、高性能で拡張性の高いキー/バリューストレージ方式と、豊富な機能を持つ従来のRDBMS方式とのギャップを埋め、両者の長所を融合させることです。公式サイトによると、Mongoは以下のようなシナリオでの使用に適している。

ウェブサイトのデータ。Mongoはリアルタイムの挿入、更新、クエリに最適で、Webサイトのリアルタイムデータストレージに必要なレプリケーションと高いスケーラビリティを持っています。

キャッシュ:Mongoはその高いパフォーマンスから、情報インフラのキャッシュ層としても適しています。システムを再起動すると、Mongo が構築した持続的なキャッシュ層が、下位のデータソースに過負荷をかけるのを防いでくれます。

大容量、低価値のデータ。従来のリレーショナル・データベースを用いてデータを保存するにはコストがかかる場合があり、それまではプログラマが従来のファイルをストレージとして選択することが多いようです。

スケーラビリティの高いシナリオ。Mongoは数十台から数百台のサーバーで構成されるデータベースに適しています。MongoのロードマップにはすでにMapReduceエンジンのビルトインサポートが含まれています。

オブジェクトやJSONデータの保存に。MongoのBSONデータ形式は、文書化された形式での保存やクエリに最適です。

当然ながら、MongoDBの使用には適していないなどの制限があります。

高度なトランザクションシステム:銀行や会計システムなど。大量のアトミックで複雑なトランザクションを必要とするアプリケーションには、やはり従来のリレーショナル・データベースの方が適しています。

従来のビジネス・インテリジェンス・アプリケーション。問題に特化した BI データベースは、高度に最適化されたクエリを生成するのに有効であろう。このようなアプリケーションでは、データウェアハウスがより適切な選択となる場合があります。

SQLが必要な問題

MongoDBはOS X、Linux、Windowsをサポートし、Python、PHP、Ruby、Java、C++言語用のドライバ、Erlangや.NETなどのプラットフォーム用のドライバを提供する。

カートゥーン MongoDBの長所と短所

SQLかNoSQLか?それは質問だ! SQL対NoSQLの議論は尽きることがありませんが、実際のところ、すべてのアプリケーションシナリオに適したテクノロジーというのは存在しません。

これからMongoDBを使おうとしている学生さんに少しでも参考になればと思い、MongoDBのメリットとデメリットをまとめました。

長所

速い! (もちろん、これは特定のアプリケーションに依存します。一般的なリレーショナルデータベースよりも5ビット程度高速です)

非常にスケーラブル - ペタバイトのストレージも楽々(ただし、ペタバイトのストレージは必要ないかもしれない、10TBで十分かも)。

非常に優れたレプリケーションモデル(レプリカセット)を持っている

非常によく開発されたJava APIを持っています

保存形式はJsonで、Javaやjavascirptで扱うにはとても良いものです。

メンテナンスも非常に簡単で、管理者を専任にする必要もありません。

非常に活発なコミュニティがある(私が上げたバグを20分以内に直してもらえた。ありがとうエリオット)

彼のバージョン管理はとても明確です。

MongoDBの背後にある会社(10gen)は、明日にでもMongoDBにお金を投資する準備ができています。

デメリット :

アプリケーションの経験不足、関連するNoSQL製品の経験が皆無。

プロジェクトが比較的新しい

以前のストレージと比較して、データのリレーショナルな操作が存在しなくなった。

さらに興味深い画像を添付します。

MongodbデータベースとMemcachedキャッシングの利点と役割の詳細分析

この記事では、MemcachedとMongodbに関するいくつかの見解と、このアプリケーションを組み合わせることでどのようなメリットがあるのかを詳しく説明しています。

メムキャッシュ

  私が考えるMemcachedの利点は、以下のように集約されます。

  1) 分散型であること。メモリ4Gのマシンを10台から構築可能 大きさが足りないと思えば、マシンを増やせばいいのです。このような大規模なメモリプールは、ホットなビジネスデータのほとんどを保持することができ、メモリはデータベースの読み取り要求のほとんどをブロックすることができるので、データベースへのかなりの圧力を解放することができるのです。

  2)一点突破。Webサーバやアプリサーバが負荷分散を行う場合、それぞれのメモリに保持されるキャッシュが異なる場合があり、データの同期が必要な場合に問題となる(それぞれ単独で期限切れとなるか、同期用にデータを分散するか?) また、データの同期が必要ない場合でも、データの不整合により、ユーザーが不親切なユーザー体験をする可能性があります。

  3)強力なパフォーマンス データベースと比較すると、確かに根底ではメモリの読み書きとディスクの読み書きの効率に桁違いの差があることは疑う余地がない。時々、我々は貧しいデータベースの読み取り/書き込みに文句を言うとき、ディスクIOを見ることができ、それが実際にボトルネックである場合、どのような強力なデータベースがインストールされていると推定され、強力かどうかは、このデータベースが完全にメモリを利用する方法だけですファイルすることはできません。

  しかし、どのような場合でも、キャッシュの代わりにMemcachedを使用することはあまりお勧めできません。

  1) Valueが特に大きい場合、適さない。これは、Memcachedがデフォルトで1MのValueしかサポートしていないためです(Keyの制限は最大の問題ではありません)。実際、実用的な観点からは、非常に大きなデータをMemcachedに保存することはお勧めしません。なぜなら、シリアライズとデシリアライズのプロセスがあり、それが消費するCPUを甘く見てはいけないからです。むしろ、取り出して直接出力したり、取り出して加工せずにそのまま使ったりするのに向いています。

  Memcachedはデフォルトで最大30日で期限切れとなり、また、メモリ使用量の制限に達した後、最も使用されていないデータを再取得するようになっています。そのため、静的変数として使用する場合は、この点を考慮してデータを再初期化する必要があります。実際には、キャッシュだから取得して保存し、なければ再取得して再キャッシュする処理が必要であり、常に存在すると考えるのではなく、このように考えるべきでしょう。

  確かにMemcachedを使う上での問題点やベストプラクティスはあります。

  MemcachedはKey/Valueのプールで、誰でも乗れるパブリックカーに過ぎません。このようなパブリックなリソースを、使う人がみんな自分のルールに従って使っていると、問題が起きやすいと思うんです。そこで、Key値の指定に名前空間のような概念を用いて、ある機能のためのKeyの範囲、つまりプレフィックスを各ユーザーが明確に知ることができるようにするのがよいでしょう。クリアする必要がある場合、すべてのKeyをクリアするのではなく、この仕様に従って自分なりのバッチを探し出し、それをクリアすればよいという利点があります。もちろん、バージョンアップの概念を使っている人もいるので、古いKeyはそのまま通過させ、時期が来れば自然に空になる。でも、Keyの指定は必ずしておいた方がいいし、統計的に楽です。

  2)Valueの組織化。つまり、保存するデータの粒度、例えばリストを保存する場合、1つずつ保存するか、1つのキーとして統一して保存するかは、業務によって異なる。粒度が小さいのであれば、取得時に一括で取得でき、保存時に一括で保存できるのがベストである。考えてみてください。あるページが100行のデータを出力する必要があり、それぞれを1回ずつ取得する必要がある場合、ページへの接続を数百回行うことはパフォーマンスの問題になるでしょうか?

  では、Memcachedは主にどのような用途に使われるのでしょうか。

  実際には、分散キャッシュを適用できないか検討するために、メモリ上でキャッシュを行う場所が考えられると思いますが、主な用途としては、フロントエンドやミドルで読み取り要求をブロックしてWebサーバアプリサービスを解放することです