web-dev-qa-db-ja.com

いつRedisに行きますか?いつMongoDBに?

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

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

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

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

467
guilin 桂林

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

たとえば、多くの クエリ が必要な場合は、主に開発者がRedisを使用するのが面倒です。ここで、データはさまざまな特殊なデータ構造に格納され、効率のためのオブジェクト。 MongoDBでは、構造がデータ間でより一貫しているため、同じクエリが簡単になる場合があります。一方、Redisでは、これらのクエリに対する応答の まったくの速度 が、データが格納される可能性のあるさまざまな構造に対処するための余分な作業に対する見返りです。

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

例えば。 cache layerはおそらくRedisでより良い実装が可能です。より多くのスキーマ対応データについては、MongoDBが優れています。 [注:MongoDBとRedisは技術的にスキーマレスです]

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

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

309
Shekhar

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

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

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

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

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

  • Redisは、データに基づいた仮定を行いません。

    Redisは便利なデータ構造(セット、ハッシュ、リストなど)を提供しますが、データの保存方法を明示的に定義する必要があります。簡単に言うと、RedisとMongoDBを使用して同様のことを実現できます。 Redisは単純に高速ですが、プロトタイピングには適していません。これは、通常MongoDBを好むユースケースの1つです。それに加えて、Redisは本当に柔軟です。それが提供する基礎となるデータ構造は、高性能DBシステムの構成要素です。

Redisを使用する場合

  • キャッシング

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

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

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

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

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

  • 気にしない場合thatスケーリングについては大したことはありません。

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

MongoDBを使用する場合

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

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

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

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

TL; DR-パフォーマンスが重要で、データの最適化と整理に時間をかけたい場合は、Redisを使用します。 -DBについてあまり心配することなくプロトタイプを構築する必要がある場合は、MongoDBを使用します。

参考文献:

236
Alexander Gugel

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を選びます。甘い。変更し続けるモデルがあるため、データモデルの変更はこれ以上ありません。

223
Gabe Rainbow

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

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

16
stackex

答えるのが難しい質問 - ほとんどの技術ソリューションと同様に、それは本当にあなたの状況に依存します。

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

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

11

(この記事の執筆時点での)すべての答えは、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 正確に いくつかの値のサブセット、 all いくつかの値のサブセット、または any いくつかの値のサブセットを含む文書を照会することができます。つまり、Accounts = ["379-1111", "379-2574"]を検索しても上記のものが見つからないということです。 Accounts includes ["379-1111"]を検索して上記の文書を見つけることができます。 Accounts includes any of ["974-3785","414-6731"]を検索して上記を見つけ、アカウントに "974-3785"が含まれている文書があれば、それを見つけることができます。

文書は必要なだけ奥行きがあります。 PhoneNumber.Mobileは配列、あるいはサブドキュメント(PhoneNumber.Mobile.WorkPhoneNumber.Mobile.Personal)さえも保持できます。データが高度に構造化されている場合、文書はリレーショナルデータベースから大きく向上したものです。

データの大部分がフラットでリレーショナル、そして厳密に構造化されている場合は、リレーショナルデータベースを使用する方が得策です。繰り返しになりますが、重要なのは、データモデルが相互に関連するCSVファイルの集まりとXML/JSON/YAMLファイルの集まりのどちらに適しているかということです。

ほとんどのプロジェクトでは、SQLストアとドキュメントストアのどちらにも当てはまらないいくつかの小さな分野では、妥協する必要があります。広範囲のデータ(多数の列、行は無関係)を格納する大規模で複雑なプロジェクトでは、あるデータをあるモデルに格納し、別のデータを別のモデルに格納することは意味があります。 FacebookはSQLとグラフデータベースの両方を使用します(データはノードに配置され、ノードは他のノードに接続されます)。 Craigslistは以前はMySQLとMongoDBを使用していましたが、完全にMongoDBへの移行を検討していました。これらは、1つのモデルの下に置くと、データの範囲と関係が重大な障害に直面する場所です。

Redis:Key-Value

Redisは、最も基本的にはKey-Valueストアです。 Redisはそれをキーにして単一の値を調べることを可能にします。 Redis自体は文字列、リスト、ハッシュ、その他いくつかのものを保存できます。ただし、名前で検索するだけです。

キャッシュの無効化は、コンピュータサイエンスにとって難しい問題の1つです。もう一つは物事の命名です。つまり、バックエンドまでの何百もの過剰な検索を避けたい場合はRedisを使用しますが、いつ新しい検索が必要になるかを把握する必要があります。

無効化の最も明白なケースは書き込み時の更新です。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とAssemblyを組み合わせてすべてを書く場所に依存します。ほとんどのアプリケーションは、一般化されたケースを処理し、RedisやMemcachedなどのキャッシングシステムを使用します。これは、高性能SQLデータベースやドキュメントストアよりもはるかに高速です。

10
John Moser

Redisはメモリ内データストア、ディスクへの状態を持続させることができます(再起動後の回復を可能にするため)。ただし、メモリ内データストアであるということは、データストアのサイズを意味します。 Redisがシステム上の他の多くのプロセスとそのスペースを共有しているので、実際には、これははるかに少なくなるでしょう(物理RAM +スワップスペース)。そしてそれがシステムのメモリ空間を使い果たした場合、それはおそらくオペレーティングシステムによって殺されるでしょう。

Mongoはディスクベースデータストア)です。これはワーキングセットが物理RAMに収まるときに最も効率的です(すべてのソフトウェアと同様)。 Mongoデータベースのサイズの制限、設定オプション、利用可能なディスク容量、その他の問題は、データベースのサイズが一定の制限を超えると実用的でなくなるか、非効率的になる可能性があることを意味します。

RedisとMongoはどちらも、高可用性、バックアップ、およびデータストア全体のサイズを増やすためにクラスタ化できます。

10
aaa90210

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

RedisはMongoより10倍速いと言っていました。それはもう本当ではないかもしれません。 MongoDBは(私が正しく覚えていれば)メモリの設定が同じである限り、ドキュメントの保存とキャッシュのためにmemcacheを打ち負かすと主張しました。

とにかく。 Redis、MongoDBはいいですね。あなたが下部構造を気にし、集約が必要な場合はMongoDBに行きます。キーと値を保存することがあなたの主な関心事であれば、それはRedisに関するものです。 (または他のキーバリューストア).

2
Martin Kersten

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

RedisはKey/Valueデータベースです、そしてそれはそれを超高速にするインメモリストレージを使用しています。これは、データのキャッシュや一時的なデータストレージ(メモリ内)に適しており、ほとんどのクラウドプラットフォーム(Azure、AWSなど)でサポートされているため、メモリ使用量は拡張可能です。限られたリソース、それはメモリ使用量を検討してください。

一方、MongoDBは文書データベースです。大きなテキスト、画像、ビデオなど、トランザクション以外のデータベースで行うことのほとんどすべてを維持するのに適しています。たとえばブログやソーシャルネットワークを開発したい場合、MongoDBは適切な選択です。スケールアウト戦略で拡張可能です。記憶媒体としてディスクを使用するので、データは永続化されます。

2
akazemis

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

1
Denys