467

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

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

それらはどちらも素晴らしいものであり、私は可能な限りRedisをデプロイに使用したいのですが、コーディングは困難です。私はできるだけMongoDBを開発に使用したいのですが、高価なマシンが必要です。

それで、あなたはそれらの両方の使用についてどう思いますか?いつRedisを選ぶの? MongoDBを選ぶとき

10 답변


310

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

例えば、あなたがたくさん必要な場合問い合わせるつまり、開発者がRedisを使用するのは面倒なことになります。そこでは効率のためにオブジェクトの種類ごとにカスタマイズされたさまざまな特殊なデータ構造にデータが格納されます。 MongoDBでは、構造がデータ間でより一貫しているため、同じクエリが簡単になる場合があります。一方、Redisでは、全くのスピードこれらのクエリに対する応答の利点は、データの格納に使用される可能性があるさまざまな構造に対処するための余分な作業に対する見返りです。

MongoDBは、伝統的なDBとSQLの経験を持つ開発者にとって、シンプルさ、より短い学習曲線を提供します。しかし、Redisの非伝統的なアプローチは、学ぶためにより多くの努力を必要としますが、より大きな柔軟性を必要とします。

例えば。 AキャッシュlayerはおそらくRedisにもっと良く実装できます。より多くのスキーマ対応データについては、MongoDBが優れています。[注:MongoDBとRedisはどちらも技術的にスキーマレスです]

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

最後に、私は今までにあなたが見たことを願っていますhttp://antirez.com/post/MongoDB-and-Redis.html


  • fyi、mongodbはスキーマレスです。 - Özgür
  • MogoDBはスキーマレスです。データベースに保存されるデータが大きくなるにつれて、MongoDBはRedisよりもはるかに高速であることを証明します。 Redisは、保存されているデータが小さい場合に限り高速です。 - Anderson
  • 私はMongoDBがスキーマレスであり、それをそのままにしておくというアプローチが大好きです。それらを必要とする人のためにスキーマを実装するために著者。マングースあなたがそれらを必要とするなら、使いやすいスキーマを紹介する素晴らしいORMです:) - Chev
  • あなたはredisデータベースのサイズがマシンのRAMの量によって制限されることを知っているべきです。それよりも大きいと、クラスタリングは手動で集中的なものと考える必要があります。 - Akash Agrawal
  • MongoDBはスキーマを強制しませんが、誰かがスキーマなしでそれを使用するケースを見たいのですが…それはあなたがスキーマという言葉を定義する方法のすべてです。 - Robbie Guilfoyle

236

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

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

    MongoDBは、ハッカソン、スタートアップ、または挿入したデータに対するクエリ方法がわからない場合に適しています。 MongoDBは、基盤となるスキーマを想定していません。 MongoDBはスキーマレスで非リレーショナルですが、これはスキーマがまったくないという意味ではありません。それは単にあなたのスキーマがあなたのアプリで定義されている必要があることを意味します(例えばMongooseを使用して)。それ以外にも、MongoDBはプロトタイプの作成や物事の試行に最適です。その性能はそれほど素晴らしいものではなく、Redisと比較することはできません。

  • 既存のアプリケーションを高速化するためにRedisを使用してください。

    Redisは簡単に統合することができますLRUキャッシュ。 Redisをスタンドアロンのデータベースシステムとして使用することはめったにありません( "key-value"ストアとして参照することを好む人もいます)。 CraigslistのようなWebサイトプライマリデータベースの横にあるRedis。 Antirez(Redisの開発者)は、Lamernewsを使用してRedisをスタンドアロンのデータベースシステムとして使用することが実際に可能であることを実証しました。

  • Redisはあなたのデータに基づいていかなる仮定もしません。

    Redisは有用なデータ構造(例えばセット、ハッシュ、リスト)の束を提供します、しかしあなたはあなたがあなたのデータを保存したい方法を明示的に定義しなければなりません。一言で言えば、RedisとMongoDBを使用して同様のことを実現できます。 Redisは単純に高速ですが、プロトタイピングには適していません。それはあなたが通常MongoDBを好むであろうユースケースです。それに、Redisは本当にフレキシブル。それが提供する基礎となるデータ構造は、高性能DBシステムのビルディングブロックです。

いつRedisを使うのですか?

  • キャッシング

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

  • あなたのDB設計について考えるのに十分な時間があるなら。

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

  • 必要なら本当にハイパフォーマンス。

    Redisが提供するパフォーマンスを破ることはほぼ不可能です。あなたのデータベースがあなたのキャッシュと同じくらい速いことを想像してみてください。それがRedisをリアルデータベース。

  • 気にしないのならそれスケーリングについての多く。

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

MongoDBを使用する場合

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

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

  • スキーマをすばやく変更する必要があるとき

    スキーマがないので!従来のリレーショナルDBMSでテーブルを変更するのは、非常に費用がかかり、時間がかかります。 MongoDBは、基礎となるデータに多くの仮定をしないことでこの問題を解決します。それにもかかわらず、スキーマを定義することを必要とせずに可能な限り最適化しようとします。

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

参考文献:


  • あなたのDB設計について考えるのに十分な時間があるなら。それを実現するために:あなたはSOデータを保存したいとします。モンゴで:入れ子にされた答えとコメントで完全な質問を単にダンプしてくださいレディスに次のことをする必要があります。SO on redis - Abhishek Gupta

223

Redisあなたがphpでサイトを書いたとしましょう。何らかの理由で、それは人気になり、それはその時代を先取りしているか、それにポルノを持っています。あなたは、このphpが非常におかしくなり過ぎていることを理解します、「彼らは単にページを待つのに10秒も待たないので私はファンを失うつもりです」。 WebページにはURLが常に変わることはないことに突然気付くでしょう。そうすると主キーが変わるので、ディスクは低速でphpはさらに低速ですが、メモリは高速です。 :(そして、あなたはメモリとこのURLを使って "key"と呼ぶウェブページのコンテンツを "value"と呼ぶストレージメカニズムを作ります。それがすべてです - keyとcontent。あなたはそれを "ミームキャッシュ"と呼びます。あなたはRichard Dawkinsがすごいから好きだし、リスのようにあなたのhtmlをキャッシュすることも、あなたのがらくたのphpコードを書き直す必要もないことも、あなたは幸せだ。他の人は猫の画像を混乱させることがあります。

モンゴあなたはサイトを書きました。あなたはたくさんの、そしてあらゆる言語で書かれていますね。あなたはあなたの時間の多くがそれらの悪臭を放つSQL句を書くのに費やされていることを認識しています。あなたはDBAではありません、まだあなたはそこにいます、愚かなSQLステートメントを書いています...ただ1つではなく、至る所でおかしくなっています。 msgstr "これを選択してください。"しかし、特にあなたはいらいらするWHERE句を覚えています。姓が「ソーントン」に、映画が「悪いサンタ」に等しい場合。うーん。 「なぜそれらのDBAが単に仕事をしてストアドプロシージャを提供してくれないのですか」と思います。それからミドルネームのようなマイナーなフィールドを忘れて、テーブルを削除し、10Gのビッグデータをすべてエクスポートし、この新しいフィールドを使って別のフィールドを作成し、データをインポートする必要があります。あいさつ文、称号のようながらくたを覚えていることに加えて、アドレスを持つ外部キーを追加してください。それからあなたはlastnameがlastNameであるべきだと考えます。 1日にほとんど1人が変わります。それならあなたはdarnitと言います。私はこのデータモデルbsを気にすることなく、Webサイト/システムにアクセスして書く必要があります。つまり、「SQLを書くのは嫌いです。SQLを使わないで、やめてください」とグーグルが言って、「nosql」とポップアップしたら、何かを読んで、スキーマなしでデータをダンプするだけだという。あなたは先週の大失敗がもっとテーブルを落として微笑んだのを覚えています。それからaptレンタルサイトの 'airbud'のような何人かの大物がそれを使っているのであなたはmongoを選びます。甘い。変更し続けるモデルがあるため、データモデルの変更はこれ以上ありません。


  • どういう意味You don't need to rewrite your crap php code?、k-v storeはこれをどのように解決しますか? :) - Roy Lee
  • @ Roylee彼は遅くて狂ったphpがhtmlでウェブページを出力することを意味します。より速く/より効率的にするために手間をかけてコードを書き直す代わりに、最初にphpを1回実行し、その後永久に実行します。構築したWebページをhvmlでk-vストアを使用して呼び戻します。 - Mikepote
  • あなたがこの物語を語った方法は、スキーマレスが素晴らしい理由を私がついに概念化するのを助けました!その力を理解するためにSQLに対処しなければならなかった数年間の私を救っただけです。 - Nick Pineda
  • 'これ以上モデルの変更はありません'本当に状況を把握していません。既存のすべてのエントリを更新するためのデータモーションコードを作成しない限り、「N'」のようになります。少しずつ異なるモデルがすべて同じDBに同時に存在するため、コードを作成する際には、DBから何かを読み込むときにどのモデルを扱っているのかを把握する必要があります。 - Terry Coatta
  • 私が今まで見た中で絶対的な最良の答えの1つ。それは素晴らしい内容を持っていて、そして実際に私を大声で笑わせる(文字通り笑ではない) - colbyJax

16

たぶん、このリソースは両者の間の決定を手助けするのに役立ちます。 それはまた他のいくつかのNoSQLデータベースを論じ、そして特性と共に短い特徴のリストを提供します。「私はそれを使うだろう」それぞれの説明

http://kkovacs.eu/cassandra-vs-mongodb-vs-couchdb-vs-redis


11

答えるのが難しい質問 - ほとんどの技術的解決策と同様に、それはあなたの状況に本当に依存します、そしてあなたが解決しようとしている問題を述べていないので、誰でも解決策を提案できますか?

あなたはそれらのどちらが満足しているか見るために両方をテストする必要がありますきみのニーズ。

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


10

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

モンゴはディスクベースデータストア、それがあるときそれが最も効率的ですワーキングセット(すべてのソフトウェアと同様に)物理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つです。もう一つは物事の命名です。つまり、バックエンドまでの何百もの過剰な検索を避けたい場合はRedisを使用しますが、いつ新しい検索が必要になるかを把握する必要があります。

無効化の最も明白なケースはwrite on updateです。user:Simon:lingots = NOTFOUNDそうかもしれないSELECT Lingots FROM Store s INNER JOIN UserProfile u ON s.UserID = u.UserID WHERE u.Username = Simonそして結果を保存する100のようにSET user:Simon:lingots = 100。それならSimon 5 lingotsを授与するとあなたは読むuser:Simon:lingots = 100SET user:Simon:lingots = 105、そしてUPDATE Store s INNER JOIN UserProfile u ON s.UserID = u.UserID SET s.Lingots = 105 WHERE u.Username = Simon。これであなたはあなたのデータベースとRedisに105を持ち、そして得ることができますuser: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;

の結果を更新したばかりなのでGetStatsFromDatabase("Simon")、あなたは落とさなければなりませんtemplates:*:Simonキーバリューキャッシュからこれらのテンプレートをレンダリングしようとすると、アプリケーションはデータベース(PostgreSQL、MongoDB)からデータを取得してそれをテンプレートに挿入します。次に結果をRedisに保存します。そして、次回その出力ブロックを表示するときに、データベースクエリやテンプレートのレンダリングを気にする必要はありません。

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

結論

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


  • "キャッシュの無効化はコンピュータサイエンスの深刻な問題の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を考慮に入れてください。

リンクされた質問


関連する質問

最近の質問