いつRedisするのですか?いつMongoDBを使うのですか?[閉まっている]


466

RedisとMongoDBの比較ではありません。私はそれらが異なることを知っています。パフォーマンスとAPIはまったく異なります。

Redisは非常に高速ですが、APIは非常に「アトミック」です。MongoDBはより多くのリソースを消費しますが、APIは非常に使いやすく、とても満足しています。

どちらもすばらしいので、できる限りRedisをデプロイで使用したいのですが、コーディングするのが難しいです。MongoDBをできる限り開発で使用したいのですが、高価なマシンが必要です。

では、両方の使用についてどう思いますか?いつRedisを選ぶのですか?いつMongoDBを選ぶのですか?

回答:


308

私が言うには、それはあなたがどのような開発チームの種類とあなたのアプリケーションのニーズに依存します。

たとえば、大量のクエリが必要な場合、ほとんどの場合、開発者がRedisを使用するほうが手間がかかります。データをさまざまな特殊なデータ構造に格納し、効率を高めるためにオブジェクトのタイプごとにカスタマイズします。MongoDBでは、データ全体で構造がより一貫しているため、同じクエリの方が簡単な場合があります。一方、Redisでは、これらのクエリへの応答速度非常に速いため、データの保存に使用される可能性のあるさまざまな構造を処理するための余分な作業が必要になります。

MongoDBは、従来のDBおよびSQLの経験を持つ開発者に、シンプルではるかに短い学習曲線を提供します。ただし、Redisの従来とは異なるアプローチでは、学ぶのにより多くの労力が必要ですが、柔軟性は高くなります。

例えば。キャッシュ層は、おそらくより良いのRedisで実現することができます。よりスキーマ可能なデータについては、MongoDBの方が優れています。 [注:MongoDBとRedisはどちらも技術的にスキーマレスです]

あなたが私に尋ねた場合、私の個人的な選択はほとんどの要件に対してRedisです。

最後に、http://antirez.com/post/MongoDB-and-Redis.htmlをご覧になったことを願っています


16
fyi、mongodbはスキーマレスです。
Özgür

18
MogoDBはスキーマレスです。そして、データベースに格納されたデータがどんどん大きくなるにつれて、MongoDBはそれがRedisよりもはるかに高速であることを証明しています。Redisは、保存されているデータが小さい場合にのみ高速になります。
アンダーソン

4
MongoDBのアプローチはスキーマレスであり、スキーマを必要とする人のためにスキーマを実装するのはORM作成者に任せるのが好きです。Mongooseは、必要に応じて使いやすいスキーマを導入する素晴らしいORMです:)
Chev

18
redisデータベースのサイズは、マシンのRAMの容量によって制限されることを知っておく必要があります。それより大きく、手動で集中的なクラスタリングを考える必要があります。
Akash Agrawal 14

4
MongoDBはスキーマを強制しませんが、誰かがスキーマなしでそれを使用するケースを見たいです...それは、スキーマという単語を定義するすべての方法です
Robbie Guilfoyle

236

この質問がかなり古いことに気づきました。それにもかかわらず、私は以下の側面を追加する価値があると考えています:

  • データのクエリ方法がわからない場合は、MongoDBを使用してください。

    MongoDBは、ハッカソン、スタートアップ、または挿入したデータのクエリ方法がわからない場合に最適です。MongoDBは、基礎となるスキーマを想定していません。MongoDBはスキーマレスで非リレーショナルですが、これはスキーマがないことを意味するものではありません。これは単に、スキーマをアプリで定義する必要があることを意味します(例:Mongooseを使用)。さらに、MongoDBはプロトタイピングや物事を試すのに最適です。そのパフォーマンスはそれほど優れておらず、Redisと比較することはできません。

  • 既存のアプリケーションを高速化するには、Redisを使用します。

    RedisはLRUキャッシュとして簡単に統合できます。Redisをスタンドアロンのデータベースシステムとして使用することは非常にまれです(「キー値」ストアとして参照することを好む人もいます)。CraigslistのようなWebサイトでは、プライマリデータベースの横にRedisを使用しています。Antirez(Redisの開発者)は、Lamernewsを使用して、Redisをスタンドアロンのデータベースシステムとして実際に使用できることを実証しました。

  • Redisはユーザーのデータに基づいていかなる仮定も行いません。

    Redisは一連の有用なデータ構造(セット、ハッシュ、リストなど)を提供しますが、データの格納方法を明示的に定義する必要があります。一言で言えば、RedisとMongoDBを使用して同様のことを実現できます。Redisは単純に高速ですが、プロトタイピングには適していません。これは、一般的にMongoDBを好む1つの使用例です。その上、Redisは本当に柔軟です。それが提供する基本的なデータ構造は、高性能DBシステムのビルディングブロックです。

いつRedisを使用するのですか?

  • キャッシング

    MongoDBを使用したキャッシングは、あまり意味がありません。遅すぎるでしょう。

  • DB設計について考える時間がある場合。

    ドキュメントをRedisに単純に投入することはできません。データを保存および整理する方法を考える必要があります。1つの例は、Redisのハッシュです。これらは「従来の」ネストされたオブジェクトとはかなり異なります。つまり、ネストされたドキュメントを格納する方法を再考する必要があります。1つの解決策は、ハッシュ内に別のハッシュへの参照を格納することです(キーのようなもの:[2番目のハッシュのID])。別のアイデアは、それをJSONとして保存することです。これは、* SQLバックグラウンドを持つほとんどの人にとって直感に反するようです。

  • 本当に高いパフォーマンスが必要な場合。

    Redisが提供するパフォーマンスを超えることはほぼ不可能です。データベースがキャッシュと同じくらい高速であることを想像してみてください。それが、Redisを実際のデータベースとして使用しているような感じです。

  • あなたは気にしない場合はそのスケーリングについて多くを。

    Redisのスケーリングは、以前ほど難しくありません。たとえば、複数のRedisインスタンス間でデータを分散するために、一種のプロキシサーバーを使用できます。マスタースレーブレプリケーションはそれほど複雑ではありません、複数のRedisインスタンス間でキーを配布することは、アプリケーションサイトで(たとえば、ハッシュ関数、Moduloなどを使用して)行う必要があります。比較によるMongoDBのスケーリングは、はるかに簡単です。

MongoDBを使用する場合

  • プロトタイピング、スタートアップ、ハッカソン

    MongoDBは、ラピッドプロトタイピングに最適です。それにもかかわらず、パフォーマンスはそれほど良くありません。また、ほとんどの場合、アプリケーションで何らかのスキーマを定義する必要があることにも注意してください。

  • スキーマをすばやく変更する必要がある場合。

    スキーマがないから!従来のリレーショナルDBMSでテーブルを変更すると、コストがかかり、処理速度が遅くなります。MongoDBは、基礎となるデータについて多くの仮定を行わないことにより、この問題を解決します。それにもかかわらず、スキーマを定義する必要なく、可能な限り最適化を試みます。

TL; DR-パフォーマンスが重要で、データの最適化と整理に時間を費やす気がある場合は、Redisを使用します。-DBをあまり気にせずにプロトタイプを作成する必要がある場合は、MongoDBを使用します。

参考文献:


3
DB設計について考える時間がある場合。それを実現するには、SOデータを格納したいとします。 モンゴでは:ネストされた回答とコメントを含む完全な質問を単純にダンプしますが、redisでは次のようにする必要があります。SOon redis
Abhishek Gupta 14

223

Redis。あなたがphpでサイトを書いたとしましょう。なんらかの理由で人気が出て、時代を先取りしたり、ポルノを掲載したりしています。このphpの動作が非常に遅いことに気づきました。「ファンがページを10秒間待たないため、ファンを失うことになります。」Webページには一定のURL(変更されることはありません、whoa)、主キーがあることに突然気づき、ディスクが低速でphpがさらに低速でもメモリは高速であることを思い出します。:(次に、メモリとこのURLを使用して「キー」と呼ばれるストレージメカニズムを作成し、Webページのコンテンツが「値」と呼ぶことにしました。キーとコンテンツだけです。「memeキャッシュ」と呼びます。リチャードドーキンスはすばらしいので、好きです。リスのようにhtmlをキャッシュして、ナッツをキャッシュします。がらくたのphpコードを書き直す必要はありません。あなたは幸せです。次に、他の人がそれを行ったことに気づきますが、他の人は猫の混乱した画像を持っているため、Redisを選択します。

モンゴ。あなたはサイトを書きました。あなたは多くのことを、そして任意の言語で書きました。あなたの時間の多くはこれらの臭いSQL句を書くことに費やされていることに気づきました。あなたはdbaではありませんが、あなたはまだ愚かなSQLステートメントを書いています...ただ1つではなく、どこでもおかしくなっています。「これを選択して、それを選択してください」。しかし、特にあなたは苛立たしいWHERE句を覚えています。ラストネームは「ソーントン」、映画は「バッドサンタ」です。ああ。あなたは、「なぜそれらのdbasは単に仕事をして、私にいくつかのストアドプロシージャを与えないのですか?」次に、ミドルネームなどのいくつかのマイナーフィールドを忘れてから、テーブルを削除し、10Gのビッグデータをすべてエクスポートして、この新しいフィールドで別のフィールドを作成し、データをインポートします。これは、次の14日間で10回繰り返されますあいさつ文、タイトル、さらに、アドレス付きの外部キーを追加します。次に、lastnameがlastNameであることを理解します。ほぼ1人が1日に変化します。次に、darnitと言います。このデータモデルを気にしないでください。「グーグル、「SQLを書くのは嫌い、SQLを使わないで、止めて」」とググってみますが、 'nosql'がポップアップし、何かを読んだら、スキーマなしでデータをダンプするだけです。あなたは先週の大失敗を思い出してテーブルを落とし笑顔を覚えています。次に、適切なレンタルサイトである「エアバッド」などの大物が使用しているため、mongoを選択します。甘い。変更し続けるだけのモデルがあるので、これ以上データモデルは変更されません。


どういう意味You don't need to rewrite your crap php code?ですか、kv storeはこれをどのように解決しますか?:)
ロイ・リー

13
@Roylee彼は遅くてくだらないphpがHTMLでウェブページを出力することを意味します。面倒にコードを書き直してコードをより速く/より効率的にする代わりに、phpを最初に1回実行し、その後ずっと実行します。kvストアを使用して、事前に構築されたWebページをhtmlで呼び出します。
Mikepote

あなたがこの話をした方法は、スキーマレスが素晴らしい理由を最終的に概念化するのに役立ちました!力を理解するためにSQLに対処する必要があった数年前に私を救いました。
Nick Pineda 2016

4
「これ以上モデルを変更しない」というのは、状況を正確に捉えるものではありません。既存のすべてのエントリを更新するデータモーションコードを記述しない限り、同じDBにすべて同時に存在する「N」個のわずかに異なるモデルがあり、コードがいつどのモデルを処理するかを把握する必要がありますDBから何かを読み取ります。
Terry Coatta 2016年

2
私が今まで見た中で絶対的なベストアンサーの1つ。素晴らしいコンテンツがあり、実際に私を大声で笑わせています(文字通りではありません)
colbyJax


11

答えるのが難しい質問-ほとんどのテクノロジーソリューションと同様に、それは実際の状況に依存します。解決しようとしている問題について説明していないため、どのようにしてソリューションを提案できますか?

それらの両方をテストして、どちらがニーズを満たしいるかを確認する必要があります。

そうは言っても、MongoDBは高価なハードウェアを必要としません。他のデータベースソリューションと同様に、より多くのCPUとメモリを使用するとより適切に機能しますが、特に初期の開発目的の場合は、確かに要件ではありません。


10

Redisはメモリ内のデータストアであり、状態をディスクに永続化できます(再起動後の回復を可能にするため)。ただし、メモリ内データストアであることは、(単一ノード上の)データストアのサイズがシステム上の合計メモリ領域(物理RAM +スワップ領域)を超えることはできないことを意味します。実際には、Redisがそのスペースをシステム上の他の多くのプロセスと共有しているため、これよりはるかに少なく、システムのメモリスペースを使い果たすと、オペレーティングシステムによって強制終了される可能性があります。

Mongoはディスクベースのデータストアであり、ワーキングセットが物理RAM(すべてのソフトウェアと同様)に収まる場合に最も効率的です。ディスクベースのデータであることは、Mongoデータベースのサイズに本質的な制限がないことを意味しますが、構成オプション、使用可能なディスク容量、およびその他の懸念事項により、特定の制限を超えるデータベースサイズが非現実的または非効率になる場合があります。

RedisとMongoの両方をクラスター化して、高可用性とバックアップを実現し、データストアの全体的なサイズを増やすことができます。


10

(この記事の執筆時点での)すべての回答は、Redis、MongoDB、およびおそらくSQLベースのリレーショナルデータベースがそれぞれ本質的に同じツールである「データの保存」であると想定しています。彼らはデータモデルをまったく考慮していません。

MongoDB:複雑なデータ

MongoDBはドキュメントストアです。SQL駆動のリレーショナルデータベースと比較するには:リレーショナルデータベースは、インデックス化されたCSVファイルに単純化され、各ファイルはテーブルです。ドキュメントストアは、インデックス化されたJSONファイルに単純化されます。各ファイルはドキュメントであり、複数のファイルがグループ化されています。

JSONファイルの構造は、XMLやYAMLファイル、およびPythonのように辞書に似ているので、データをそのような階層で考えてください。インデックスを作成するときは、構造がキーになります。ドキュメントには名前付きのキーが含まれ、さらにドキュメント、配列、またはスカラー値が含まれます。以下のドキュメントを検討してください。

{
  _id:  0x194f38dc491a,
  Name:  "John Smith",
  PhoneNumber:
    Home: "555 999-1234",
    Work: "555 999-9876",
    Mobile: "555 634-5789"
  Accounts:
    - "379-1111"
    - "379-2574"
    - "414-6731"
}

上記のドキュメントには、PhoneNumber.Mobile値を持つキーがあります555 634-5789。キーPhoneNumber.Mobileが何らかの値を持つドキュメントのコレクションを検索できます。それらは索引付けされています。

また、Accounts複数のインデックスを保持する配列もあります。文書を照会することが可能であるAccounts含まれている正確に、値のいくつかのサブセットを、すべての値のいくつかのサブセットの、またはいずれかを値のいくつかのサブセット。つまりAccounts = ["379-1111", "379-2574"]、上記を検索して見つけることはできません。Accounts includes ["379-1111"]上記のドキュメントを検索して見つけることができます。Accounts includes any of ["974-3785","414-6731"]上記を検索し、アカウント「974-3785」を含むドキュメントがあれば、それを検索できます。

ドキュメントは必要なだけ深く入ります。 PhoneNumber.Mobile配列、またはサブドキュメント(PhoneNumber.Mobile.WorkおよびPhoneNumber.Mobile.Personal)さえ保持できます。データが高度に構造化されている場合、ドキュメントはリレーショナルデータベースからの大きなステップアップです。

データの大部分がフラットで、リレーショナルで、厳格に構造化されている場合は、リレーショナルデータベースの方が適しています。繰り返しになりますが、大きな兆候は、データモデルが相互に関連するCSVファイルのコレクションとXML / JSON / YAMLファイルのコレクションのどちらに最適であるかです。

ほとんどのプロジェクトでは、SQLまたはドキュメントストアが適合しない一部の小さな領域で、軽微な回避策を受け入れて、妥協する必要があります。広範囲のデータを格納するいくつかの大規模で複雑なプロジェクト(多くの列、行は無関係)の場合、一部のデータをあるモデルに格納し、他のデータを別のモデルに格納することは理にかなっています。FacebookはSQLとグラフデータベースの両方を使用します(データはノードに入れられ、ノードは他のノードに接続されます)。Craigslistは以前はMySQLとMongoDBを使用していましたが、完全にMongoDBに移行することを検討していました。これらは、データのスパンと関係が1つのモデルの下に置かれた場合、大きなハンディキャップに直面する場所です。

Redis:Key-Value

Redisは、基本的にはKey-Valueストアです。Redisでは、キーを指定して単一の値を検索できます。Redis自体は、文字列、リスト、ハッシュ、およびその他のいくつかのものを格納できます。ただし、名前でのみ検索します。

キャッシュの無効化は、コンピュータサイエンスの難しい問題の1つです。もう1つは、名前を付けることです。つまり、バックエンドへの何百もの過剰なルックアップを回避したい場合はRedisを使用しますが、新しいルックアップが必要な場合はそれを把握する必要があります。

無効化の最も明らかなケースは、書き込み時の更新です。を読み取ると、結果をとして保存user:Simon:lingots = NOTFOUNDできます。あなたはサイモン5 lingotsを授与する場合次に、あなたが読んで、と。これで、データベースとRedisに105があり、データベースにクエリを実行しなくても取得できます。SELECT Lingots FROM Store s INNER JOIN UserProfile u ON s.UserID = u.UserID WHERE u.Username = Simon100SET user:Simon:lingots = 100user:Simon:lingots = 100SET user:Simon:lingots = 105UPDATE Store s INNER JOIN UserProfile u ON s.UserID = u.UserID SET s.Lingots = 105 WHERE u.Username = Simonuser:Simon:lingots

2番目のケースは、依存情報の更新です。ページのチャンクを生成し、それらの出力をキャッシュするとします。ヘッダーには、プレーヤーの経験、レベル、金額が表示されます。プレーヤーのプロフィールページには、統計情報を表示するブロックがあります。など。プレイヤーはある程度の経験を積む。さて、今あなたは、いくつか持っているtemplates:Header:Simontemplates:StatsBox:Simontemplates:GrowthGraph:Simonなどなどを、あなたがキャッシュされてきたところ、半ダースのデータベースクエリの出力は、テンプレートエンジンを介して実行フィールド。通常、これらのページを表示するときは、次のように言います。

$t = GetStringFromRedis("templates:StatsBox:" + $playerName);
if ($t == null) {
  $t = BuildTemplate("StatsBox.tmpl",
                     GetStatsFromDatabase($playerName));
  SetStringInRedis("Templates:StatsBox:" + $playerName, $t);
}
print $t;

の結果を更新したばかりなので、Key-ValueキャッシュGetStatsFromDatabase("Simon")から削除templates:*:Simonする必要があります。これらのテンプレートのいずれかをレンダリングしようとすると、アプリケーションはデータベース(PostgreSQL、MongoDB)からデータをフェッチしてテンプレートに挿入します。次に、結果をRedisに保存します。次回、その出力ブロックを表示するときに、データベースクエリを作成したり、テンプレートをレンダリングしたりする必要はありません。

Redisでは、パブリッシャーサブスクライブメッセージキューなども実行できます。それは完全に別のトピックです。ここでのポイントは、Redisはキーバリューキャッシュであり、リレーショナルデータベースやドキュメントストアとは異なります。

結論

ニーズに基づいてツールを選択してください。最大のニーズは通常、コードがどれほど複雑でエラーを起こしやすいかを決定するデータモデルです。専用のアプリケーションは、Cとアセンブリを組み合わせてすべてを書き込む場所であるパフォーマンスに依存します。ほとんどのアプリケーションは、一般化されたケースを処理し、RedisやMemcachedなどのキャッシュシステムを使用します。これは、高性能SQLデータベースやドキュメントストアよりもはるかに高速です。


2
「キャッシュの無効化は、コンピューターサイエンスの難しい問題の1つです。もう1つは、名前を付けることです。」仰るとおり!
Arel

2

RAMが十分にある場合は、どちらも使用しないでください。RedisとMongoDBは、汎用ツールの代償を払っています。これは多くのオーバーヘッドをもたらします。

RedisはMongoよりも10倍速いという格言がありました。それはもう真実ではないかもしれません。MongoDB(私が正しく覚えている場合)は、メモリ構成が同じである限り、ドキュメントの保存とキャッシュでmemcacheに勝ると主張しました。

とにかく。Redisは良い、MongoDBは良い。部分構造に関心があり、集計が必要な場合は、MongoDBを使用してください。キーと値の保存がRedisに関するすべての主な関心事である場合。(または他のキー値ストア)。


2

RedisとMongoDBはどちらも非リレーショナルデータベースですが、カテゴリは異なります。

RedisはKey / Valueデータベースであり、メモリ内ストレージを使用しているため、非常に高速です。これは、(メモリ内の)キャッシュと一時的なデータストレージの良い候補であり、ほとんどのクラウドプラットフォーム(Azure、AWSなど)がサポートしているため、メモリ使用量はスケーラブルですが、マシンで使用する場合は、リソースが限られている場合は、メモリ使用量を考慮してください。

一方、MongoDBはドキュメントデータベースです。大きなテキスト、画像、動画など、トランザクション以外のデータベースで行うほとんどすべてのことを維持するのに適したオプションです。たとえば、ブログやソーシャルネットワークを開発する場合は、MongoDBが適切な選択肢です。スケールアウト戦略によりスケーラブルです。ストレージメディアとしてディスクを使用するため、データは永続化されます。


1

プロジェクトの予算が十分であれば、環境に十分なRAMメモリを確保できる場合、答えはRedisです。特に、クラスター機能を備えた新しいRedis 3.2を考慮に入れます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.