キャッシングには Redis サーバーを搭載したRuby Webアプリを使用しています。代わりに Memcached をテストする必要がありますか?
何が私たちにもっと良いパフォーマンスをもたらすでしょうか? RedisとMemcachedの間に賛否両論がありますか。
考慮すべき点
2017年6月3日更新
Redisはmemcachedよりも強力で、普及しており、サポートも優れています。 Memcachedは、Redisが実行できることのほんの一部しか実行できません。 Redisはそれらの機能が重なるところでさえより良いです。
新しいものは、Redisを使ってください。
どちらのツールも、キャッシュとして役立つ、強力で高速のインメモリデータストアです。どちらもデータベースの結果、HTMLフラグメント、その他生成にコストがかかる可能性がある何かをキャッシュすることで、アプリケーションのスピードを上げるのに役立ちます。
同じことに使われると、元の質問の「考慮すべき点」を使って比較することができます。
Memcachedは単純な揮発性キャッシュサーバーです。値が最大1MBの文字列に制限されている場合は、キーと値のペアを保存できます。
これは得意ですが、それだけです。あなたは非常に高速でそれらのキーによってそれらの値にアクセスすることができます、しばしば飽和可能な利用可能なネットワークあるいはメモリ帯域幅さえ。
Memcachedを再起動するとデータは消えます。これはキャッシュとしては問題ありません。そこに重要なものを何も保管しないでください。
高性能または高可用性が必要な場合は、サードパーティ製のツール、製品、およびサービスを利用できます。
Redisはmemcachedと同じ仕事をすることができ、より良い仕事をすることができます。
Redisは キャッシュ としても機能することができます。キーと値のペアも保存できます。 Redisでは、最大512MBまで可能です。
持続性をオフにすることができ、それは再起動時にあなたのデータを喜んで失います。キャッシュを再起動後も存続させたい場合は、それを実行することもできます。実際、これがデフォルトです。
それは超高速でもあり、しばしばネットワークやメモリの帯域幅によって制限されます。
1つのインスタンスのredis/memcachedがワークロードにとって十分なパフォーマンスを得られない場合は、redisが明確な選択です。 Redisには クラスタサポート が含まれ、高可用性ツールが付属しています( redis-sentinel ) "箱の中に"過去数年にわたって、redisはサードパーティ製ツールの明確なリーダーとしても浮上してきました。 Redis Labs、Amazonなどの企業は、多くの便利なredisツールとサービスを提供しています。 redis周辺の生態系はもっと大きいです。大規模デプロイメントの数は、現在はmemcachedよりも多い可能性があります。
Redisは単なるキャッシュ以上のものです。インメモリデータ構造サーバです。以下に、Redcがmemcachedのような単純なキー/値キャッシュであること以外にできることの概要を簡単に説明します。 ほとんどののredisの機能はmemcachedができないことです。
Redisはmemcachedよりも文書化されています。これは主観的な場合がありますが、常に真実になっているようです。
redis.io は、簡単にナビゲートできる素晴らしいリソースです。それはあなたが ブラウザ でredisを試すことを可能にし、さらにあなたはdocsの中のそれぞれのコマンドであなたにインタラクティブな例を生きさせる。
Memcachedの2倍のredisのスタックオーバーフロー結果があります。 Googleの検索結果の2倍より多くの言語でより簡単にアクセスできる例より積極的な開発。より積極的なクライアント開発これらの測定値はそれほど個別に意味するわけではないかもしれませんが、組み合わせてredisのサポートと文書化がより明確でより最新のものであるという明確な絵を描きます。
デフォルトでは、redisはスナップショットと呼ばれるメカニズムを使ってデータをディスクに永続化します。 RAMが十分に利用できる場合は、パフォーマンスをほとんど低下させることなく、すべてのデータをディスクに書き込むことができます。ほぼ無料です。
スナップショットモードでは、突然のクラッシュによって少量のデータが失われる可能性があります。データが失われたことがないことを確認する必要がある場合は、心配しないでください。redisにはAOF(Append Only File)モードもあります。この永続モードでは、データは書き込まれたとおりにディスクと同期できます。これは最大書き込みスループットをあなたのディスクが書くことができるがそれでも高速にすることができますが、それでもかなり速いはずです。
必要に応じて永続性を微調整するための設定オプションはたくさんありますが、デフォルトは非常に賢明です。これらのオプションは、データを保存するための安全で冗長な場所としてのredisの設定を容易にします。それは本物のデータベースです。
Memcachedは文字列に限定されていますが、Redisはさまざまなデータ型に対応できるデータ構造サーバーです。また、これらのデータ型を最大限に活用するために必要なコマンドも提供されています。
最大512MBのサイズの単純テキストまたはバイナリ値。これは唯一のデータ型redisとmemcached共有ですが、memcached文字列は1MBに制限されています。
Redisでは、ビット単位の操作、ビットレベルの操作、浮動小数点の増分/減分のサポート、範囲のクエリ、およびマルチキー操作のためのコマンドを提供することによって、このデータ型を活用するためのより多くのツールを提供します。 Memcachedはそれをサポートしていません。
文字列はあらゆる種類のユースケースに役立ちます。そのため、memcachedはこのデータ型だけで非常に便利です。
ハッシュは、キー値ストア内のキー値ストアのようなものです。それらは文字列フィールドと文字列値の間でマッピングします。ハッシュを使ったフィールド - >値マップは、通常の文字列を使ったキー - >値マップよりもわずかにスペース効率が良い。
ハッシュは名前空間として、あるいは多くのキーを論理的にグループ化したいときに便利です。ハッシュを使用すると、すべてのメンバーを効率的に取得したり、すべてのメンバーを期限切れにしたり、すべてのメンバーを一緒に削除したりできます。グループ化する必要のあるキー/値ペアがいくつかあります。
ハッシュの使用例の1つは、アプリケーション間でユーザープロファイルを保存することです。ユーザーIDをキーとして格納されたredisハッシュを使用すると、単一のキーの下に格納された状態で、ユーザーに関する必要なだけのデータを格納できます。プロファイルを文字列にシリアル化する代わりにハッシュを使用する利点は、1つのアプリケーションが他のユーザーによる変更を上書きすることを心配せずに、異なるアプリケーションでユーザープロファイル内の異なるフィールドを読み書きできることです。データ)。
Redisリストは順序付けられた文字列の集まりです。それらは、リストの上または下(別名:左または右)から値を挿入、読み取り、または削除するために最適化されています。
Redisには、アイテムをプッシュ/ポップする、リスト間でプッシュ/ポップする、リストを切り捨てる、範囲クエリを実行するなどの、リストを活用するための多数の コマンド があります。
リストは、非常に丈夫でアトミックなキューを作ります。これらは、ジョブキュー、ログ、バッファ、その他多くのユースケースに最適です。
セットは、順序付けられていない一意の値の集まりです。値がセット内にあるかどうかをすばやく確認し、値をすばやく追加または削除し、他のセットとの重複を測定できるように最適化されています。
これらはアクセスコントロールリスト、ユニークビジタートラッカー、その他多くのものに最適です。ほとんどのプログラミング言語は似たようなものを持っています(通常Setと呼ばれます)。これはそのようなもので、配布されているだけです。
Redisはセットを管理するためにいくつかの コマンド を提供します。セットの追加、削除、確認などの明らかなものがあります。それで、ランダムなアイテムを飛び出したり読んだりするような、それほど明白でないコマンドや、他のセットとの和集合や交差を実行するためのコマンドもあります。
ソートセットも一意の値の集まりです。名前が示すように、これらのものは順序付けられています。それらはスコア順に並べられ、次に辞書式に並べられます。
このデータタイプはスコアによる素早い検索に最適化されています。その間の最高値、最低値、または任意の範囲の値を取得するのは非常に高速です。
あなたが彼らのハイスコアと一緒にソートセットにユーザーを追加する場合、あなたはあなた自身が完璧なリーダーボードを持っています。新しいハイスコアが出てきたら、それらをハイスコアで再びセットに追加するだけで、リーダーボードの順番が変わります。また、ユーザーが最後にアクセスした時間とアプリケーションでアクティブになっているユーザーを追跡するのにも役立ちます。
同じスコアを持つ値を格納すると、それらは辞書式に並べられます(アルファベット順に考えます)。これはオートコンプリート機能のようなものに役立ちます。
ソートセット コマンド の多くは、セットのコマンドに似ていますが、スコアパラメータが追加されていることもあります。スコアを管理し、スコアで照会するためのコマンドも含まれています。
Redisには、地理データの保存、取得、および測定のためのいくつかの コマンド があります。これには、半径クエリとポイント間の距離の測定が含まれます。
技術的にはredisの地理データはソートセットに格納されているので、これは本当に別のデータ型ではありません。これはソートセットの上の拡張です。
Geoのように、これらは完全に別のデータ型ではありません。これらは、文字列データをビットマップまたはハイパーログのように扱うことができるコマンドです。
ビットマップは、私がStrings
の下で参照したビットレベル演算子の対象です。このデータ型は、redditの最近のコラボレーションアートプロジェクトの基本的な構成要素です。 r/Place 。
HyperLogLogを使用すると、驚くほど正確にほぼ無限のユニークな値をカウントするために、非常に少量のスペースを使用できます。最大16KBを使用すると、たとえその数が数百万になっていても、あなたのサイトへのユニークビジターの数を効率的に数えることができます。
Redisのコマンドはアトミックです。つまり、redisに値を書き込むとすぐに、その値はredisに接続されているすべてのクライアントに表示されます。その値が伝搬するのを待つ必要はありません。技術的にmemcachedもアトミックですが、redisではmemcachedを超えてこれらすべての機能が追加されているため、これらすべての追加のデータ型と機能もアトミックであることは注目に値します。
リレーショナルデータベースのトランザクションとまったく同じではありませんが、redisには「楽観的ロック」を使用する トランザクション もあります( / マルチ / EXEC )。
Redisは ' パイプライン処理 'と呼ばれる機能を提供します。実行したいredisコマンドがたくさんある場合は、一度に1つずつ送信するのではなく、パイプラインを使用してredisに一度に送信することができます。
通常、redisまたはmemcachedのいずれかに対してコマンドを実行すると、各コマンドは別々の要求/応答サイクルになります。パイプライン処理を使用すると、redisは複数のコマンドをバッファして一度にすべて実行し、1回の返信ですべてのコマンドに対するすべての応答を返します。
これにより、一括インポートや他の多くのコマンドを伴うアクションでさらに高いスループットを達成できます。
Redisには pub/sub機能 専用の コマンド があり、redisが機能するようにします。高速メッセージ放送局として。これにより、単一のクライアントが、チャネルに接続されている他の多数のクライアントにメッセージをパブリッシュすることができます。
Redisは、ほとんどすべてのツールと同様にpub/subも行います。 RabbitMQ のような専用のメッセージブローカーは、特定の分野では利点がありますが、同じサーバーで永続的な永続キューやその他のデータ構造をパブに提供できるという事実/ subワークロードが必要とする可能性が高いので、Redisがその仕事にとって最も簡単でシンプルなツールであることがしばしば証明されます。
Redis自身のSQLやストアドプロシージャのように luaスクリプト を考えることができます。それはそれ以上でもそれ以下でもありますが、その類推は大体うまくいきます。
多分あなたはredisに実行させたい複雑な計算があるでしょう。トランザクションをロールバックして、複雑なプロセスのすべてのステップがアトミックに行われるという保証が必要な場合もあります。これらの問題やその他の多くの問題は、luaスクリプトを使って解決できます。
スクリプト全体がアトミックに実行されるので、自分のロジックをluaスクリプトに収めることができれば、楽観的ロックトランザクションで混乱を避けることができます。
上記のように、redisにはクラスタリングのサポートが組み込まれており、redis-sentinel
という独自の高可用性ツールにバンドルされています。
ためらうことがなければ、新しいプロジェクト、またはまだmemcachedを使用していない既存のプロジェクトについては、memcachedを再実行することをお勧めします。
上記は私がmemcachedを好きではないように聞こえるかもしれません。それどころか、それは強力で、単純で、安定した、成熟した、そして堅くなったツールです。 redisより少し速いというユースケースさえあります。私はmemcachedが大好きです。私はそれが将来の開発にとってあまり意味があるとは思わない。
Redisはmemcachedのすべてのことを行いますが、多くの場合より優れています。 memcachedのパフォーマンス上の利点は、マイナーおよびワークロード固有のものです。また、redisが高速になるワークロードや、redisができるmemcachedのワークロードが単純にできないワークロードもあります。機能面での巨大な面と、非常に高速で効率的なツールであるという点で、パフォーマンスのわずかな違いは小さいように見えますが、スケーリングについて心配しなければならないインフラストラクチャの最後の部分になる可能性があります。
Memcachedがより理にかなっているシナリオは1つだけです。つまり、memcachedは既にキャッシュとして使用されています。 memcachedで既にキャッシュしているのであれば、それが必要に応じて使用し続けてください。 redisに移行するのは努力の価値がないでしょう。もしあなたがredisをキャッシュのためだけに使用しようとしているなら、それはあなたの時間に見合うだけの十分な利益を提供しないかもしれません。 memcachedが自分のニーズを満たしていない場合は、おそらくredisに移行する必要があります。これは、memcachedを超えて拡張する必要がある場合でも、追加の機能が必要である場合でも同じです。
以下の場合はRedisを使用
キャッシュ内のアイテムを選択的に削除/期限切れにする必要があります。 (あなたにはこれが必要です)
特定の種類のキーをクエリする機能が必要です。式'blog1:posts:*'、 'blog2:categories:xyz:posts:*'。そうそう!これはとても重要です。これを使用して、特定の種類のキャッシュ項目を選択的に無効にします。これを使用して、フラグメントキャッシュ、ページキャッシュ、特定のタイプのARオブジェクトのみなどを無効にすることもできます。
永続性(再起動のたびにキャッシュをウォームアップする必要がある場合を除き、これも必要になります。ほとんど変更されないオブジェクトには非常に重要です。)
次の場合はmemcachedを使用
私の経験からすると、私はMemcachedよりもRedisの方がずっと安定しています。
Memcachedはマルチスレッドで高速です。
Redisにはたくさんの機能があり、非常に高速ですが、イベントループに基づいているため完全に1つのコアに制限されています。
両方使用しています。 Memcachedはオブジェクトのキャッシュに使用され、主にデータベースの読み込み負荷を軽減します。 Redisは、時系列データをロールアップするのに便利なソートセットなどに使用されます。
これはすでに受け入れられている答えへのコメントとして投稿するには長すぎるので、私はそれを別の答えとして入れました
考慮すべき1つのことは、あなたがあなたのキャッシュインスタンスに強い上限メモリ制限があると予想するかどうかということです。
Redisは大量の機能を備えたnosqlデータベースであり、キャッシングは使用できるオプションの1つに過ぎないため、必要に応じてメモリを割り当てます。オブジェクトを多く配置するほど、使用されるメモリも多くなります。 maxmemory
オプションは、上限メモリ使用量を厳密には強制しません。キャッシュを操作すると、キーは削除され期限切れになります。鍵のサイズがすべて同じではないために、内部メモリの断片化が発生する可能性があります。
デフォルトでは、redisは jemalloc メモリアロケータを使用します。これは、メモリの小型化と高速化の両方に最善を尽くしますが、汎用のメモリアロケータであり、不可能です。大量の割り当てやオブジェクトの削除を高速で実行します。このため、一部の負荷パターンでは、内部の断片化のためにredisプロセスが明らかにメモリをリークすることがあります。たとえば、7 Gb RAMのサーバーを使用していて、永続的なLRUキャッシュとしてredisを使用する場合、maxmemory
を5Gbに設定したredisプロセスでは、ますます多くのメモリーが使用されることになります。最終的には、メモリ不足のキラーが妨害するまでtotal RAM limitを押してください。
memcachedは、まったく異なる方法でメモリを管理するため、上記のシナリオにより適しています。 memcachedは、1つの大きなメモリチャンク(必要なものすべて)を割り当ててから、独自に実装された スラブアロケータ を使用して、このメモリを単独で管理します。さらに、オブジェクトサイズを考慮してLRU追い出しが行われるとき、実際には スラブ単位のLRUアルゴリズム が使用されるため、memcachedは内部の断片化を低く抑えることを試みます。
そうは言っても、memcachedは、メモリ使用量を強制したり予測したりする必要がある環境では、依然として強力な位置を占めています。 10〜15k op/sの作業負荷で、最新の安定版redis(2.8.19)をドロップイン式の非永続LRUベースのmemcachedの代替として使用しようとしましたが、メモリリークが発生しました。同じ理由で、同じワークロードで1日かそこらでAmazonのElastiCache redisインスタンスがクラッシュしました。
Memcachedは単純なキー/値ストアであることと、key => STRINGを行うことを得意としています。これにより、セッションの保存に非常に役立ちます。
Redisはkey => SOME_OBJECTをするのが得意です。
それは本当にあなたがそこに入れようとしているものに依存します。私の理解するところでは、パフォーマンスの観点では、それらはかなり均等です。
客観的なベンチマークを見つけることもできれば幸いです。
筆記スタイルを気にしないのであれば、Systoiletブログの Redis vs Memcached はユーザビリティの観点から読む価値がありますが、前のコメントの前後に必ず読んでください。パフォーマンスに関する結論を引き出す。いくつかの方法論上の問題(シングルスレッドのビジーループテスト)があります、そしてRedisは記事が書かれて以来、いくつかの改良をしました。
ちょっと混乱することなくベンチマークリンクは完全ではないので、 DormondoのLiveJournal と Antirez Weblog でいくつかの矛盾するベンチマークもチェックしてください。
編集 - Antirezが指摘しているように、Systoilet分析はかなり構想が悪い。シングルスレッドの不足を超えても、これらのベンチマークにおけるパフォーマンスの格差の多くは、サーバーのスループットではなくクライアントライブラリに起因する可能性があります。 Antirezウェブログ のベンチマークは、実際にはもっと同じりんごとりんご(同じ口を持つ)の比較を示しています。
私は自分が取り組んできたキャッシングプロキシでmemcachedとredisの両方を一緒に使用する機会を得ました。
レディス>
1)クラスタ上でキャッシュコンテンツのインデックスを作成するために使用されます。私は、Redisクラスター全体に10億以上の鍵を広げています。Redisの応答時間はかなり短く安定しています。
2)基本的に、それはキー/バリューストアなので、アプリケーション内のどこにでも似たようなものがある場合は、redisを使用して面倒な作業をすることができます。
3)Redis persistence、failover、backup(AOF)はあなたの仕事を容易にします。
Memcache>
1)はい、キャッシュとして使用できる最適化されたメモリです。私は、1 MB以下のサイズで非常に頻繁にアクセスされるキャッシュコンテンツ(毎秒50ヒット)を保存するためにそれを使用しました。
2)単一のコンテンツサイズが1 MBを超える場合、memcachedには16 GBのうち2 GBしか割り当てませんでした。
3)内容が限界に近づくにつれて、時々統計の中で応答時間が長くなっています(redisの場合はそうではありません)。
全体的な経験を求めるなら、Redisは設定が簡単で、環境に優しく、安定した堅牢な機能を備えているので非常に柔軟です。
さらに、この リンク で利用可能なベンチマーク結果があります。
お役に立てれば!!
もう1つの利点は、memcacheがキャッシングシナリオでどのように振る舞うかが非常に明確になることです。一方、redisは通常永続データストアとして使用されます。容量。
私が取り組んできたアプリの中には、データの振る舞いを明確にするためだけに使用するものもあります - memcacheのもの、それがない場合を処理するコードを書く - redisのもの、あることに頼ります。
それ以外は、Redisは一般的に、機能が豊富で柔軟なため、ほとんどのユースケースで優れていると見なされています。
テスト。簡単なベンチマークをいくつか実行します。私は長い間、私はほとんどmemcachedを使っていて、Redisを新しい子供だと思っていたので、自分自身を古い学校のサイと考えていました。
現在の会社では、Redisがメインキャッシュとして使用されていました。私がいくつかのパフォーマンス統計を掘り下げて単純にテストを始めたとき、Redisは、パフォーマンスの点では、MySQLに匹敵するか、または最低でも 遅い でした。
単純化されていますが、MemcachedはRedisを水から吹き飛ばしました 完全に 。それははるかに良く拡大しました:
また、memcachedの立ち退きポリシーは、私の見解でははるかに優れているため、キャッシュが処理できる以上のデータを処理しながら、全体的により安定した平均応答時間が得られます。
ベンチマークの結果、Redisは、私たちの場合、非常にパフォーマンスが悪いことがわかりました。これは多くの変数と関係があると私は信じています。
個人的に、私はRedisの作者が並行性とマルチスレッド化について持っている見解を共有しません。
Memcachedが単なるキャッシュであるのに対して、redisが(キャッシュ+データ構造)の組み合わせであると言っても、それは間違いではありません。
ここで指摘されていない大きな違いの1つは、Memcacheは常に上限メモリを持っているのに対し、Redisはデフォルトではそうではありません(しかし設定することができます)。もしあなたが常にキー/値を一定時間保存したい(そしてメモリ不足のために決してそれを追い出したくない)のであれば、Redisを使用したいと思うでしょう。もちろん、あなたはメモリ不足の問題も抱えています...
Redis-2.2.2およびmemcachedに対して100,000の固有のキーと値を設定および取得するための非常に単純なテスト。どちらもlinux VM(CentOS)上で動作しており、私のクライアントコード(下に貼り付けたもの)はWindowsデスクトップ上で動作します。
Redis
100000個の値を格納するのにかかる時間は= 18954msです
100000個の値をロードするのにかかる時間は= 18328msです
Memcached
100000個の値を格納するのにかかる時間は= 797msです
100000個の値を取得するのにかかる時間は= 38984msです
Jedis jed = new Jedis("localhost", 6379);
int count = 100000;
long startTime = System.currentTimeMillis();
for (int i=0; i<count; i++) {
jed.set("u112-"+i, "v51"+i);
}
long endTime = System.currentTimeMillis();
System.out.println("Time taken to store "+ count + " values is ="+(endTime-startTime)+"ms");
startTime = System.currentTimeMillis();
for (int i=0; i<count; i++) {
client.get("u112-"+i);
}
endTime = System.currentTimeMillis();
System.out.println("Time taken to retrieve "+ count + " values is ="+(endTime-startTime)+"ms");
私たちはRedisを私たちの仕事のための負荷離陸として考えました。 HttpRedis2Moduleなどのnginxのモジュールを使うことでスピードが速くなると思いましたが、AB-testでテストすると間違っていることがわかりました。
モジュールが悪いか、レイアウトが悪いのかもしれませんが、非常に単純な作業で、phpでデータを取得してからMongoDBに格納するほうがさらに高速でした。私達はキャッシングシステムとしてそしてそのphpとMongoDBとしてAPCを使用しています。それはnginx Redisモジュールよりはるかに高速でした。
私のヒントはそれをあなた自身でテストすることです、そうすることはあなたの環境のための結果をあなたに示すでしょう。私たちはRedisを使うことは意味がないので私たちのプロジェクトでは不要であると決めました。
残っている最大の理由は特殊化です。
Redisはさまざまなことを実行できますが、その副作用の1つとして、開発者が同じインスタンス上でさまざまな機能セットを多数使用することがあります。 RedisのLRU機能をLRUではないハードデータストレージと一緒にキャッシュに使用している場合は、メモリ不足になる可能性があります。
特定のシナリオを回避するために専用のRedisインスタンスをLRUインスタンスとしてのみ使用するように設定するのであれば、Redis over Memcachedを使用する説得力のある理由はありません。
信頼性の高い "絶対に落ちない" LRUキャッシュが必要な場合... Memcachedは設計上メモリ不足になることは不可能であり、特殊化機能によって開発者がそれを危険にさらす可能性があるため不可能です。懸念の単純な分離.
Redisがネットワーキング(TCP呼び出し)を含んでいるからといって、パフォーマンスに興味があるのであればMemcachedのほうが速くなります。内部的にもMemcacheは高速です。
それが他の答えによって言及されたようにRedisはより多くの機能を持っています。
Redisが優れています。
Redis
の長所は、
LUA
スクリプト)のサポートMemcache
はインメモリキー値キャッシュタイプのシステムです。
ここ はAmazonが提供する本当に素晴らしい記事/違いです
Redisは、memcachedと比較して明らかな勝者です。
Memcachedのプラスポイントは1つだけです。マルチスレッドで高速です。 Redisには多くの優れた機能があり、非常に高速ですが、1つのコアに制限されています。
よく私は自分のアプリ、Memcacheでセッションをキャッシュする、そしてdoctrine/ormクエリオブジェクトでredisの両方を使いました。パフォーマンスの点では、どちらもほぼ同じです。