キャッシングには、Redisサーバーを備えたRuby Webアプリを使用しています。代わりにMemcachedをテストするポイントはありますか?
何が私たちのパフォーマンスを向上させますか?RedisとMemcachedの間の長所または短所はありますか?
考慮すべき点:
- 読み取り/書き込み速度。
- メモリ使用量。
- ディスクI / Oダンプ。
- スケーリング。
キャッシングには、Redisサーバーを備えたRuby Webアプリを使用しています。代わりにMemcachedをテストするポイントはありますか?
何が私たちのパフォーマンスを向上させますか?RedisとMemcachedの間の長所または短所はありますか?
考慮すべき点:
回答:
2017年6月3日更新
Redisはmemcachedよりも強力で人気があり、サポートも優れています。Memcachedは、Redisが実行できることのごく一部しか実行できません。Redisは、機能が重複している場合でも優れています。
新しいものについては、Redisを使用してください。
どちらのツールも、キャッシュとして役立つ強力で高速なメモリ内データストアです。どちらも、データベースの結果、HTMLフラグメント、または生成にコストがかかる可能性のあるその他のものをキャッシュすることにより、アプリケーションの速度を上げるのに役立ちます。
同じことに使用した場合、元の質問の「考慮すべきポイント」を使用して比較すると、次のようになります。
Memcachedはシンプルな揮発性キャッシュサーバーです。これにより、値が最大1MBの文字列に制限されているキー/値のペアを保存できます。
これは得意ですが、それだけです。これらの値には、キーを使用して非常に高速にアクセスできます。多くの場合、利用可能なネットワークやメモリ帯域幅が飽和状態になります。
memcachedを再起動すると、データは失われます。これはキャッシュには問題ありません。あなたはそこに重要なものを保管すべきではありません。
高性能または高可用性が必要な場合は、サードパーティのツール、製品、およびサービスを利用できます。
Redisはmemcachedと同じジョブを実行でき、より適切に実行できます。
Redisはキャッシュとしても機能します。キーと値のペアも保存できます。redisでは最大512MBまで可能です。
永続化をオフにすると、再起動時にデータが失われます。再起動後もキャッシュを存続させたい場合は、再起動も可能です。実際、これがデフォルトです。
それも非常に高速で、多くの場合、ネットワークまたはメモリの帯域幅によって制限されます。
redis / memcachedの1つのインスタンスでは、ワークロードに対して十分なパフォーマンスが得られない場合は、redisが最適です。Redisにはクラスターのサポートが含まれ、高可用性ツール(redis-sentinel)が「ボックス内」に付属しています。過去数年にわたって、redisはサードパーティツールの明確なリーダーとして浮上しています。Redis Labs、Amazonなどの企業は、多くの便利なredisツールとサービスを提供しています。redisの周りの生態系ははるかに大きいです。大規模なデプロイメントの数はmemcachedの場合よりも多くなる可能性があります。
Redisは単なるキャッシュではありません。これは、インメモリデータ構造サーバーです。以下に、memcachedのような単純なキー/値キャッシュである以上にRedisが実行できることの概要を示します。redisの機能のほとんどは、memcachedでは実行できない機能です。
Redisはmemcachedよりもドキュメント化されています。これは主観的である可能性がありますが、常に真実であるようです。
redis.ioは、簡単にナビゲートできる素晴らしいリソースです。ブラウザでredisを試すことができ、ドキュメント内の各コマンドを使用したインタラクティブなライブ例も表示されます。
これで、memcachedの2倍のredisのstackoverflow結果が得られます。Googleの結果の2倍。より多くの言語でより簡単にアクセスできる例。より積極的な開発。よりアクティブなクライアント開発。これらの測定値は個別にはあまり意味がないかもしれませんが、組み合わせることで、redisのサポートとドキュメントがより大きく、より最新であることを明確に示します。
デフォルトでは、redisはスナップショットと呼ばれるメカニズムを使用してデータをディスクに永続化します。十分なRAMがあれば、パフォーマンスをほとんど低下させることなく、すべてのデータをディスクに書き込むことができます。ほとんど無料です!
スナップショットモードでは、突然のクラッシュにより、少量のデータが失われる可能性があります。絶対にデータが失われないようにする必要がある場合でも、心配しないでください。AOF(ファイルのみを追加)モードを使用すると、redisにも戻ってきます。この永続モードでは、データが書き込まれるときにデータをディスクに同期できます。これにより、最大書き込みスループットが低下してディスクが書き込み可能な速度に達する可能性がありますが、それでもかなり高速であるはずです。
必要に応じて永続性を微調整するための多くの構成オプションがありますが、デフォルトは非常に賢明です。これらのオプションにより、データを保存する安全で冗長な場所としてredisを簡単に設定できます。それは本当のデータベース。
Memcachedは文字列に制限されていますが、Redisは多くの異なるデータ型を提供できるデータ構造サーバーです。また、これらのデータ型を最大限に活用するために必要なコマンドも提供します。
最大512MBのサイズの単純なテキストまたはバイナリ値。これは、redisおよびmemcached共有の唯一のデータ型ですが、memcached文字列は1MBに制限されています。
Redisは、ビット単位の操作、ビットレベルの操作、浮動小数点のインクリメント/デクリメントのサポート、範囲クエリ、マルチキー操作のコマンドを提供することにより、このデータ型を活用するためのより多くのツールを提供します。Memcachedはそれをサポートしていません。
文字列はあらゆる種類のユースケースに役立ちます。そのため、このデータ型だけでmemcachedがかなり役立ちます。
ハッシュは、キー値ストア内のキー値ストアのようなものです。それらは文字列フィールドと文字列値の間をマッピングします。ハッシュを使用するフィールド->値マップは、通常の文字列を使用するキー->値マップよりもスペース効率が少し高くなります。
ハッシュは名前空間として、または多数のキーを論理的にグループ化する場合に役立ちます。ハッシュを使用すると、すべてのメンバーを効率的に取得したり、すべてのメンバーを一緒に期限切れにしたり、すべてのメンバーを一緒に削除したりできます。
ハッシュの使用例の1つは、アプリケーション間でユーザープロファイルを格納することです。ユーザーIDをキーとして保存されたredisハッシュを使用すると、ユーザーに関するデータのビットを必要なだけ保存しながら、それらを単一のキーの下に保存できます。プロファイルを文字列にシリアル化する代わりにハッシュを使用する利点は、あるアプリケーションが他のユーザーによって行われた変更を上書きすることを心配する必要なく、ユーザープロファイル内の異なるフィールドを異なるアプリケーションに読み書きできることです(古いものをシリアル化した場合に発生する可能性があります)。データ)。
Redisリストは、文字列の順序付けられたコレクションです。これらは、リストの上部または下部(別名:左または右)からの値の挿入、読み取り、または削除に最適化されています。
Redisには、アイテムのプッシュ/ポップ、リスト間のプッシュ/ポップ、リストの切り捨て、範囲クエリの実行など、リストを活用するための多くのコマンドが用意されています。
リストは、優れた永続的でアトミックなキューを作成します。これらは、ジョブキュー、ログ、バッファ、および他の多くの使用例に最適です。
セットは、一意の値の順序付けられていないコレクションです。これらは、値がセット内にあるかどうかをすばやく確認し、値をすばやく追加/削除し、他のセットとの重複を測定できるように最適化されています。
これらは、アクセス制御リスト、ユニークなビジタートラッカー、その他多くのものに最適です。ほとんどのプログラミング言語には同様のものがあり(通常はセットと呼ばれます)。これはそのようなもので、配布されるだけです。
Redisは、セットを管理するためのコマンドをいくつか提供しています。セットの追加、削除、チェックなどの明らかなものが存在します。したがって、ランダムなアイテムのポップ/読み取りなどのそれほど明白ではないコマンドや、他のセットとの結合や交差を実行するコマンドもあります。
並べ替えられたセットも一意の値のコレクションです。名前が示すように、これらは順序付けられています。それらはスコア順に並べられ、辞書式に並べられます。
このデータ型は、スコアによる迅速な検索のために最適化されています。最高値、最低値、またはその間の値の範囲を取得するのは非常に高速です。
ユーザーをハイスコアとともに並べ替えられたセットに追加すると、完璧なリーダーボードになります。新しいハイスコアが表示されたら、ハイスコアを付けてもう一度セットに追加するだけで、リーダーボードが再注文されます。また、ユーザーが最後にアクセスした時間と、アプリケーションでアクティブなユーザーを追跡するのにも最適です。
同じスコアで値を格納すると、それらは辞書式に順序付けされます(アルファベット順で考えてください)。これは、オートコンプリート機能などに役立ちます。
並べ替えられたセットコマンドの多くは、セットのコマンドに似ていますが、追加のスコアパラメータがある場合があります。スコアの管理とスコアによるクエリのためのコマンドも含まれています。
Redisには、地理データを保存、取得、測定するためのコマンドがいくつかあります。これには、半径クエリとポイント間の距離の測定が含まれます。
技術的にはredisの地理データはソートされたセット内に格納されるため、これは完全に別個のデータタイプではありません。ソートされたセットの上にある拡張機能です。
geoと同様に、これらは完全に別個のデータ型ではありません。これらは、文字列データをビットマップまたはハイパーログのように扱うことができるコマンドです。
ビットマップは、私が参照したビットレベルの演算子のStrings
目的です。このデータ型は、redditの最近のコラボレーションアートプロジェクトr / Placeの基本的なビルディングブロックでした。
HyperLogLogを使用すると、一定の非常に少量のスペースを使用して、ほぼ無制限の一意の値を驚異的な精度でカウントできます。〜16KBを使用するだけで、たとえその数が数百万であっても、サイトへのユニークビジターの数を効率的にカウントできます。
redisのコマンドはアトミックです。つまり、redisに値を書き込むとすぐに、その値はredisに接続されているすべてのクライアントに表示されます。その値が伝播するのを待つ必要はありません。技術的にはmemcachedもアトミックですが、redisがmemcachedを超えてこのすべての機能を追加しているため、これらすべての追加のデータ型と機能もアトミックであることは注目に値し、多少印象的です。
リレーショナルデータベースのトランザクションとはまったく異なりますが、redisにもトランザクションがあります「楽観的ロック」(WATCH / MULTI / EXEC)を使用する。
Redisは「パイプライン」と呼ばれる機能を提供します。実行する多くのredisコマンドがある場合は、パイプラインを使用して、一度にではなく一度にすべてを一度にredisに送信できます。
通常、redisまたはmemcachedのいずれかに対してコマンドを実行すると、各コマンドは個別の要求/応答サイクルになります。パイプラインを使用すると、redisは複数のコマンドをバッファーに入れて一度に実行し、すべてのコマンドに対するすべての応答を1つの応答で返すことができます。
これにより、一括インポートや、多数のコマンドを含むその他のアクションでさらに高いスループットを実現できます。
Redisにはpub / sub機能専用のコマンドがあります、redisを高速メッセージブロードキャスターとしてせることができます。これにより、単一のクライアントが、チャネルに接続されている他の多くのクライアントにメッセージを発行できます。
Redisは、ほとんどすべてのツールと同様にpub / subを実行します。RabbitMQなどの専用メッセージブローカーは特定の領域で利点があるかもしれませんが、同じサーバーがpub / subワークロードが必要とする可能性のある永続的なキューと他のデータ構造も提供できるという事実は、Redisがしばしば最も優れた最も単純なツールであることを証明します仕事で。
あなたは一種のluaスクリプトを考えることができますRedis独自のSQLやストアドプロシージャのようなます。それは多かれ少なかれですが、類推はほとんど機能します。
おそらく、redisに実行させたい複雑な計算があるかもしれません。トランザクションをロールバックする余裕がなく、複雑なプロセスのすべてのステップがアトミックに発生することを保証する必要があるかもしれません。これらの問題は、luaスクリプトで解決できます。
スクリプト全体はアトミックに実行されるため、ロジックをluaスクリプトに適合させることができれば、楽観的ロックトランザクションをいじることを回避できることがよくあります。
上記のように、redisにはクラスタリングの組み込みサポートが含まれており、と呼ばれる独自の高可用性ツールにバンドルされていますredis-sentinel
。
ためらうことがなければ、新しいプロジェクトやmemcachedをまだ使用していない既存のプロジェクトには、memcachedよりもredisをお勧めします。
上記はmemcachedが好きではないように聞こえるかもしれません。それどころか、それは強力でシンプル、安定した、成熟した、強化されたツールです。redisより少し速いユースケースもいくつかあります。memcachedが大好きです。私はそれが将来の発展のためにあまり意味がないと思います。
Redisはmemcachedが実行するすべてのことを実行します。memcachedのパフォーマンス上の利点はマイナーであり、ワークロード固有です。また、redisの方が高速になるワークロードもあり、redisが実行できるワークロードの多くはmemcachedが単純に実行できないものです。機能の巨大な湾に直面すると、小さなパフォーマンスの違いはわずかに見えます。両方のツールが非常に高速で効率的であるという事実は、スケーリングについて心配する必要があるインフラストラクチャの最後の部分である可能性が高いです。
memcachedがより意味のあるシナリオは1つだけあります。memcachedがすでにキャッシュとして使用されている場合です。memcachedですでにキャッシュしている場合は、必要に応じて使用し続けます。redisに移行する努力に値するものではない可能性が高く、キャッシュのためだけにredisを使用する場合は、時間に見合うだけの十分なメリットが得られない可能性があります。memcachedがニーズを満たしていない場合は、おそらくredisに移行する必要があります。これは、memcachedを超えてスケーリングする必要がある場合でも、追加の機能が必要な場合でも当てはまります。
次の場合はRedisを使用します
キャッシュ内のアイテムを選択的に削除/期限切れにする必要があります。(あなたはこれを必要とします)
特定のタイプのキーをクエリする機能が必要です。eq。「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を搭載したサーバーがあり、redisを非永続的なLRUキャッシュとして使用したい場合、5 GBにmaxmemory
設定されたredisプロセスが時間の経過とともにますます多くのメモリを使用し、最終的には合計RAM制限に達します。メモリ不足キラーが干渉します。
memcachedは完全に異なる方法でメモリを管理するため、上記のシナリオに適しています。memcachedは、1つの大きなメモリチャンク(必要になるすべてのもの)を割り当て、独自に実装されたスラブアロケータを使用して、このメモリを単独で管理します。さらに、memcachedは、オブジェクトのサイズを考慮してLRUエビクションが実行されるときに、実際にはスラブごとのLRUアルゴリズムを使用するため、内部の断片化を低く抑えるように努めています。
そうは言っても、memcachedは、メモリ使用量を強制したり予測可能にしたりする必要がある環境で依然として強力な地位を占めています。最新の安定したredis(2.8.19)を、10-15k op / sのワークロードでドロップインの非永続的なLRUベースのmemcachedの置き換えとして使用しようとしましたが、メモリリークが発生しました。同じ理由により、同じワークロードが1日ほどでAmazonのElastiCache redisインスタンスをクラッシュさせていました。
maxmemory
オプションは、内部メモリの断片化を考慮していません。詳細については、上記の私のコメントを参照してください。ここで説明した問題は、メモリ制限オプションが有効になっている「LRUキャッシュとしてのRedis」ページで説明されているシナリオで見られました。反対に、memcachedはメモリの断片化の問題を回避するために別のアプローチを使用しているため、そのメモリ制限ははるかに「ハード」です。
Memcachedは単純なキー/値ストアであることに長けており、キー=> STRINGを行うのが得意です。これは、セッションストレージに最適です。
Redisはkey => SOME_OBJECTを行うのが得意です。
それは本当にあなたがそこに入れようとしているものに依存します。私の理解では、パフォーマンスに関してはかなり均等です。
また、客観的なベンチマークを見つけて頑張ってください。
ひどい書き方を気にしないのであれば、SystoiletブログのRedis vs Memcachedは使いやすさの観点から読む価値がありますが、パフォーマンスについて結論を出す前にコメントで前後を読んでください。いくつかの方法論的な問題(シングルスレッドビジーループテスト)があり、Redisはこの記事の執筆以来、いくつかの改善を加えてきました。
そして、少し混乱しない限り、ベンチマークリンクは完全ではありません。 DormondoのLiveJournalとAntirez Weblog。
編集 -Antirezが指摘するように、Systoilet分析はかなり間違った考えです。シングルスレッドの不足を超えても、これらのベンチマークのパフォーマンスの違いの多くは、サーバーのスループットではなくクライアントライブラリに起因する可能性があります。Antirez Weblogのベンチマークは、実際に(同じ口で)はるかに多くのリンゴ間の比較を示しています。
私が取り組んだキャッシングプロキシでmemcachedとredisの両方を一緒に使用する機会を得ました。正確に私が何を使用したか、その背後にある理由を正確に共有させてください...
Redis>
1)クラスター全体で、キャッシュコンテンツのインデックス作成に使用されます。Redisクラスター全体で10億を超えるキーが分散しているため、Redisの応答時間は非常に短く、安定しています。
2)基本的に、それはキー/値ストアなので、アプリケーションのどこかに似たものがあったとしても、多くのことでredisを使用できます。
3)Redisの永続性、フェイルオーバー、バックアップ(AOF)により、作業が簡単になります。
Memcache>
1)はい、キャッシュとして使用できる最適化されたメモリ。私は、1 MB未満のサイズで非常に頻繁にアクセスされる(50ヒット/秒)キャッシュコンテンツを格納するために使用しました。
2)単一のコンテンツサイズが1 MBを超える場合、memcachedにも16 GBのうち2 GBのみを割り当てました。
3)コンテンツが制限に近づくにつれ、統計の応答時間が長くなることがあります(redisの場合はそうではありません)。
全体的な経験を求める場合、Redisは設定が簡単で環境に優しく、柔軟性が高く安定した堅牢な機能を備えています。
さらに、このリンクで利用可能なベンチマーク結果があり、以下は同じものからいくつかのハイライトです、
お役に立てれば!!
テスト。いくつかの簡単なベンチマークを実行します。主にmemcachedを使用し、Redisを新しい子供と見なして以来、長い間、私は古い学校のサイと考えていました。
現在の会社では、Redisがメインキャッシュとして使用されていました。いくつかのパフォーマンス統計を調べて、単純にテストを開始したとき、パフォーマンスの点では、RedisはMySQLに匹敵するか、最小限の速度でした。
Memcachedは単純化されていますが、Redisを完全に水から吹き飛ばしました。それははるかに良くスケーリングしました:
また、memcachedのエビクションポリシーは私の見解であり、はるかに適切に実装されているため、キャッシュが処理できるよりも多くのデータを処理しながら、全体的に平均応答時間がより安定しています。
一部のベンチマークは、私たちの場合、Redisのパフォーマンスが非常に低いことを明らかにしました。これは多くの変数と関係があると私は信じています:
個人的には、Redisの作者が並行性とマルチスレッド化について持っている見解を共有しません。
もう1つのボーナスは、キャッシュシナリオでmemcacheがどのように動作するかが非常に明確になることですが、redisは通常、永続的なデータストアとして使用されますが、最大に達したときにmemcached、つまり最近使用されたアイテムを削除するように動作するように構成できます容量。
私が取り組んできたいくつかのアプリは、データの動作方法を明確にするために両方を使用します-memcacheにあるもの、そこにない場合を処理するコードを記述します-redisにあるもの、そこにあることに依存しています。
それ以外の場合、Redisは一般的に、ほとんどのユースケースで優れており、機能が豊富で柔軟性があります。
memcachedが単なるキャッシュであるのに、redisが(キャッシュ+データ構造)の組み合わせであると言っても、間違いではありません。
redis-2.2.2およびmemcachedに対して10万の一意のキーと値を設定および取得するための非常に単純なテスト。どちらもLinux VM(CentOS)で実行されており、私のクライアントコード(下記に貼り付け)はWindowsデスクトップで実行されています。
Redis
100000の値を保存するのにかかる時間は= 18954ミリ秒
100000の値をロードするのにかかる時間は= 18328ms
Memcached
100000の値を保存するのにかかる時間は= 797ミリ秒
100000の値を取得するのにかかる時間は= 38984ミリ秒
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はさまざまなことを実行でき、その1つの副作用として、開発者は同じインスタンスでこれらのさまざまな機能セットの多くを使用し始めることがあります。RedisのLRU機能を、LRUではないハードデータストレージと一緒にキャッシュに使用している場合、メモリが不足する可能性があります。
特定のシナリオを回避するために専用のRedisインスタンスをLRUインスタンスとしてのみ使用するようにセットアップする場合、MemcachedよりもRedisを使用する説得力のある理由はありません。
信頼性の高い「決してダウンしない」LRUキャッシュが必要な場合... Memcachedは設計どおりにメモリを使い果たすことは不可能であり、特殊化機能は開発者がそれを危険にさらす可能性があるものにしようとするのを防ぐため、適切に機能します。懸念の単純な分離。
私たちは、Redisを作業中のプロジェクトのロードテイクオフと考えました。nginx
呼び出されたモジュールHttpRedis2Module
または類似のモジュールを使用することで、驚くほどの速度が得られると考えましたが、ABテストでテストすると、間違いが判明しました。
たぶん、モジュールが悪いか、レイアウトが悪いのかもしれませんが、それは非常に単純なタスクであり、phpでデータを取得してMongoDBに詰め込む方がより高速でした。キャッシングシステムとしてAPCを使用し、そのphpとMongoDBを使用しています。それははるかに高速でしたnginx
Redisモジュールでした。
私のヒントは、自分でテストすることです。それを実行すると、環境の結果が表示されます。私たちは、Redisを使用する必要がないと判断しました。
これは、Amazonが提供する本当に素晴らしい記事/違いです
Redisはmemcachedと比較して明らかに勝者です。
Memcachedのプラスポイントは1つだけ です。マルチスレッドで高速です。Redisには多くの優れた機能があり、非常に高速ですが、1つのコアに制限されています。
MemcachedでサポートされていないRedisの優れた点