[解決済み] Memcached vs. Redis? [クローズド]
質問
RubyのWebアプリで レディス サーバにキャッシュされます。をテストするポイントはありますか? メムキャッシュ の代わりに?
どちらがより良いパフォーマンスを発揮しますか?RedisとMemcachedの間に長所と短所はありますか?
考慮すべき点
- 読み書きの速度。
- メモリ使用量。
- ディスクI/Oのダンプ。
- スケーリング。
どのように解決するのですか?
まとめ (TL;DR)
2017年6月3日更新
Redisはmemcachedよりも強力で、より人気があり、より良くサポートされています。MemcachedはRedisができることのごく一部しかできません。両者の機能が重複している部分でもRedisの方が優れています。
新しいものには、Redisを使いましょう。
MemcachedとRedisの比較。直接比較
どちらのツールも強力で高速なインメモリデータストアであり、キャッシュとして有用である。どちらもデータベースの結果やHTMLの断片など、生成にコストがかかりそうなものをキャッシュすることで、アプリケーションの高速化に役立てることができます。
検討のポイント
同じものを使う場合、元の質問の"Points to Consider"を使って比較すると、以下のようになります。
- 読み出し/書き込み速度 : どちらも非常に高速です。ベンチマークはワークロードやバージョン、その他多くの要因によって異なりますが、一般的にredisはmemcachedと同じかほとんど同じ速さであることが示されています。私はredisをお勧めしますが、memcachedが遅いからではありません。そうではありません。
-
メモリ使用量
: Redis の方が良い。
- memcachedです。キャッシュサイズを指定し、アイテムを挿入すると、デーモンはすぐにこのサイズより少し大きいサイズになります。memcachedを再起動しない限り、そのスペースを再利用する方法はありません。すべてのキーの有効期限が切れ、データベースをフラッシュしても、設定した RAM の塊がすべて使用されます。
- redis:最大サイズの設定はあなた次第です。Redisは必要以上に使用することはなく、使わなくなったメモリはあなたに返却します。
- ランダムな文章を10万個~2KBの文字列(~200MB)を両方に保存してみました。MemcachedのRAM使用量は、~225MBに増加しました。RedisのRAM使用量は、~228MBに増加しました。両方をフラッシュした後、Redisは~29MBに減少し、Memcachedは~225MBに留まりました。両者はデータの保存方法において同じように効率的ですが、一方だけがデータを再利用することができます。
- ディスクI/Oダンプ : redisはデフォルトでこれを行い、非常に柔軟なパーシステンスを設定できるため、redisの勝利は明らかです。Memcachedはサードパーティツール無しでディスクにダンプするメカニズムを持っていません。
- スケーリング : どちらも、キャッシュとして1つ以上のインスタンスが必要になるまでに、膨大なヘッドルームを提供します。Redisはそれを超えるためのツールを備えていますが、memcachedはそうではありません。
メムキャッシュ
Memcachedはシンプルな揮発性キャッシュ・サーバです。キーと値のペアを保存することができ、値は最大1MBの文字列に制限されています。
得意といえば得意だが、それだけだ。これらの値にはキーで非常に高速にアクセスでき、ネットワークやメモリの帯域幅さえも飽和してしまうことがよくあります。
memcachedを再起動すると、データは消えてしまいます。これはキャッシュとしては問題ありません。重要なものをそこに保存するべきではありません。
高パフォーマンスや高可用性が必要な場合は、サードパーティのツール、製品、サービスが利用できます。
レディス
Redisはmemcachedと同じ仕事をすることができ、より良い仕事をすることができます。
Redisは以下のことが可能です。 キャッシュとして機能する もあります。キーと値のペアを保存することもできます。redisでは512MBまで可能です。
永続化をオフにすれば、再起動時にデータを失うこともありません。もし、キャッシュを再起動後も保持したい場合は、そのようにすることもできます。実際、これがデフォルトになっています。
また、ネットワークやメモリの帯域幅によって制限されることが多いのですが、超高速です。
redis/memcachedの1つのインスタンスではワークロードに対して十分なパフォーマンスが得られない場合、redisが明確な選択肢となります。Redisには以下が含まれます。 クラスタサポート と、高可用性ツール( レディスセンチネル を使用することができます。ここ数年、redisはサードパーティツールにおける明確なリーダーとして台頭してきました。Redis LabsやAmazonなどの企業が、多くの便利なredisツールやサービスを提供しています。redisを取り巻くエコシステムは、より大規模なものとなっています。大規模なデプロイの数は、おそらくmemcachedよりも多くなっています。
Redisスーパーセット
Redisは単なるキャッシュではありません。インメモリデータ構造サーバです。Redisがmemcachedのような単純なキー/バリューキャッシュであること以上にできることを以下に簡単に説明します。 最も の機能はmemcachedではできないことです。
ドキュメント
Redisはmemcachedよりもドキュメントが充実しています。これは主観的なことかもしれませんが、常に真実であるように思えます。
redis.io は、簡単にナビゲートできる素晴らしいリソースです。このサイトでは ブラウザでredisを試す そして、ドキュメントにある各コマンドを使ったライブのインタラクティブな例も提供しています。
現在、redisに関するstackoverflowの結果はmemcachedの2倍となっています。Google の検索結果も 2 倍になりました。より多くの言語で、より容易にアクセス可能な例です。より活発な開発。より活発なクライアント開発。これらの測定は個々にはあまり意味がないかもしれませんが、組み合わせると、redisのサポートとドキュメントがより多く、より最新であることが明確にわかります。
永続性
デフォルトでは、redisはスナップショットと呼ばれるメカニズムを使用してデータをディスクに永続化します。十分なRAMがあれば、パフォーマンスをほとんど低下させることなく、すべてのデータをディスクに書き込むことができます。ほとんど無料です
スナップショットモードでは、突然のクラッシュにより、少量のデータが失われる可能性があります。絶対にデータを失いたくない場合は、AOF (Append Only File)モードでバックアップします。この永続化モードでは、データは書き込まれるたびにディスクに同期されます。このため、最大書き込みスループットはディスクが書き込める速度に制限されますが、それでもかなり高速になるはずです。
必要であれば、パーシステンスを微調整するための多くの設定オプションがありますが、デフォルトは非常に賢明なものです。これらのオプションにより、redisを安全で冗長なデータ保存場所として簡単に設定することができます。それは リアル データベースです。
多くのデータ型
Memcachedは文字列に限定されていますが、Redisはデータ構造サーバーであり、さまざまなデータ型を提供することができます。また、これらのデータ型を最大限に活用するために必要なコマンドも提供されています。
文字列 ( コマンド )
単純なテキストまたはバイナリ値で、最大512MBのサイズがあります。これはredisとmemcachedが共有する唯一のデータ型ですが、memcachedの文字列は1MBに制限されています。
Redisは、ビット演算、ビットレベル操作、浮動小数点インクリメント/デクリメントサポート、レンジクエリ、およびマルチキーオペレーション用のコマンドを提供し、このデータ型を利用するためのより多くのツールを提供します。Memcachedはそのいずれもサポートしていません。
文字列はあらゆるユースケースで役に立つので、memcachedはこのデータ型だけでかなり便利に使えます。
ハッシュ ( コマンド )
ハッシュは、キー・バリュー・ストアの中のキー・バリュー・ストアのようなものです。文字列のフィールドと文字列の値を対応させます。ハッシュを使ったフィールドと値のマップは、通常の文字列を使ったキーと値のマップよりも、若干スペース効率が良くなります。
ハッシュは名前空間として、あるいは多くのキーを論理的にグループ化したいときに便利です。ハッシュを使えば、すべてのメンバーを効率的に取得し、すべてのメンバーをまとめて期限切れにしたり、すべてのメンバーをまとめて削除したりすることができます。グループ化する必要があるいくつかのキーと値のペアがある場合、あらゆる用途に最適です。
ハッシュの使用例として、アプリケーション間でユーザープロファイルを保存することが挙げられる。ユーザーIDをキーとして保存されたRedisハッシュは、ユーザーに関するデータを1つのキーの下に保存したまま、必要なだけのデータを保存することを可能にします。プロファイルを文字列にシリアライズする代わりにハッシュを使用する利点は、異なるアプリケーションにユーザープロファイル内の異なるフィールドを読み書きさせることができる点で、あるアプリケーションが他のアプリケーションの変更を上書きする心配がありません(これは古いデータをシリアライズした場合に起こり得ます)。
リスト ( コマンド )
Redisリストは、文字列の順序付きコレクションです。リストの上や下(別名:左や右)から値を挿入したり、読んだり、削除したりするのに最適化されています。
Redisは多くの コマンド リストを活用するためのコマンドで、アイテムのプッシュ/ポップ、リスト間のプッシュ/ポップ、リストの切り捨て、レンジクエリの実行などがあります。
リストは、耐久性があり、アトミックなキューに最適です。これらは、ジョブキュー、ログ、バッファ、および他の多くのユースケースに最適に動作します。
セット ( コマンド )
セットは、ユニークな値の順序不同のコレクションです。値がセットに含まれているかどうかをすばやくチェックし、値をすばやく追加/削除し、他のセットとの重複を測定できるように最適化されています。
これらは、アクセス制御リスト、ユニークビジタートラッカー、その他多くのものに最適です。ほとんどのプログラミング言語には、似たようなものがあります(通常、セットと呼ばれます)。これはそのようなもので、ただ分散されているだけです。
Redisはいくつかの コマンド を使用して、セットを管理します。セットの追加、削除、チェックなど、明らかなものが存在する。また、ランダムなアイテムのポップアップや読み取り、他のセットとの共用や交差を実行するコマンドなど、あまり目立たないコマンドもあります。
ソートされたセット ( コマンド )
ソートされたセットもまた、ユニークな値のコレクションです。これらは、その名の通り、並べ替えが行われます。スコアで並べられ、次に辞書順に並べられる。
このデータ型は、スコアによる素早い検索に最適化されている。最高値、最低値、またはその間の任意の範囲の値を非常に高速に取得できます。
ハイスコアと一緒にユーザーをソートされたセットに追加すれば、完璧なリーダーボードが完成します。新しいハイスコアが入ってきたら、ハイスコアと一緒に再度セットに追加すれば、リーダーボードの順番が並び替わります。また、ユーザーが最後に訪問した時間や、アプリケーションで活動しているユーザーを追跡するのにも最適です。
同じスコアを持つ値を保存すると、辞書順に並べられます(アルファベット順と同じです)。これは、オートコンプリート機能などに有効です。
ソートされた集合の多く コマンド はセット用のコマンドと似ているが、スコアパラメータが追加されている場合もある。また、スコアを管理するためのコマンドや、スコアで検索するためのコマンドも含まれています。
ジオ
Redisにはいくつかの コマンド 地理データの保存、取得、および測定に使用します。これには、半径クエリや点間距離の計測が含まれます。
技術的には、redisの地理データはソートされたセットの中に格納されているので、これは本当に独立したデータ型ではありません。ソートされたセットの上に拡張されたものです。
ビットマップとハイパーログログ
geoのように、これらは完全に別のデータ型ではありません。これらは、文字列データをビットマップかハイパーログのように扱うことができるコマンドです。
ビットマップは、私が下で参照したビットレベル演算子が
Strings
は、そのためのものです。このデータ型は、redditの最近の共同アートプロジェクトの基本的な構成要素でした。
r/Place
.
HyperLogLogを使えば、一定の極めて小さなスペースで、ほとんど無限のユニークな値を衝撃的な精度でカウントすることができます。たった16キロバイトで、あなたのサイトへのユニークビジターの数を、たとえその数が数百万人であっても、効率的に数えることができるのです。
トランザクションとアトミシティ
redisのコマンドはアトミックです。つまり、redisに値を書き込むとすぐに、redisに接続しているすべてのクライアントがその値を見ることができます。その値が伝搬するのを待つ必要はありません。技術的にはmemcachedもアトミックですが、redisはmemcachedを超えるすべての機能を追加しており、これらの追加のデータ型と機能もアトミックであることは注目に値しますし、やや印象的です。
リレーショナル・データベースのトランザクションとはちょっと違いますが、redisには トランザクション を使用した楽観的ロック( WATCH / マルチ / EXEC ).
パイプライン
Redisは、' パイプライン '. Redis のコマンドをたくさん実行したい場合、パイプラインを使用すると、一回ずつではなく一度に redis に送信することができます。
通常、redisまたはmemcachedにコマンドを実行する場合、それぞれのコマンドは個別のリクエスト/レスポンスサイクルになります。パイプラインを使えば、redisは複数のコマンドをバッファリングして一度に実行し、すべてのコマンドに対するすべてのレスポンスを一度に返信することができるのです。
これにより、バルクインポートなど、多くのコマンドを使用するアクションにおいて、さらに高いスループットを達成することができます。
パブ/サブ
Redisは コマンド に特化した pub/sub機能 Redisが高速メッセージブロードキャスターとして動作することを可能にします。これにより、単一のクライアントが、チャネルに接続された他の多くのクライアントにメッセージを発行することができます。
Redisは、ほとんどすべてのツールと同じようにpub/subを行うことができます。のような専用のメッセージブローカーは ラビットMQ しかし、同じサーバーで永続的なキューやその他のPub/Subワークロードが必要とするデータ構造を提供できるため、Redisがこの仕事に最適で最もシンプルなツールであることが証明されることが多いでしょう。
Luaスクリプト
をなんとなく考えてみてください。 ルアースクリプト は、redis独自のSQLやストアドプロシージャのようなものです。それ以上でもあり、それ以下でもあるのですが、この例えはほとんど有効です。
Redisに実行させたい複雑な計算があるのかもしれません。トランザクションをロールバックさせる余裕がなく、複雑な処理の各ステップがアトミックに行われることを保証する必要があるかもしれません。これらの問題やその他多くの問題は、luaスクリプトで解決することができます。
スクリプト全体がアトミックに実行されるため、ロジックをluaスクリプトに収めることができれば、楽観的ロックトランザクションに手を出さずに済むことが多いのです。
スケーリング
前述のとおり、redisにはクラスタリングのサポートが組み込まれており、また、独自の高可用性ツールである
redis-sentinel
.
まとめ
新しいプロジェクトや、まだmemcachedを使っていない既存のプロジェクトには、躊躇なくmemcachedよりもredisをお勧めします。
上記は、私がmemcachedを嫌いであるかのように聞こえるかもしれません。それどころか、強力で、シンプルで、安定しており、成熟し、強化されたツールなのです。redisより少し速いという使用例さえあります。私はmemcachedが大好きです。ただ、今後の開発にはあまり意味がないと思っています。
Redisはmemcachedが行うすべてのことを行うことができ、多くの場合、より優れています。memcachedのパフォーマンス上の利点はわずかで、ワークロードに依存します。また、redisがより速いワークロードもありますし、redisにできてmemcachedにできないワークロードもたくさんあります。また、redisができることで、memcachedができない作業負荷もたくさんあります。機能面での大きな隔たりや、どちらのツールも非常に高速で効率的なので、インフラのスケーリングを心配する必要がなくなるという事実を前にすると、小さな性能差は小さく感じられます。
memcachedがより理にかなっているシナリオはただ1つ、memcachedがすでにキャッシュとして使用されている場合です。memcached がすでにキャッシュとして使われている場合です。redis に移行する労力は割に合わないでしょうし、キャッシュのためだけに redis を使うのであれば、時間を割くほどのメリットはないかもしれません。もしmemcachedがあなたのニーズを満たしていないのであれば、おそらくredisに移行すべきです。これはmemcachedを超えるスケールが必要であろうと、追加機能が必要であろうと同じことです。
関連
-
[解決済み】IISで静的リソースのHTTPヘッダーに有効期限や最大年齢を設定する方法
-
[解決済み] TLBシュートダウンとは何ですか?
-
[解決済み] コンフリクトミスとキャパシティミスの違いについて
-
[解決済み] ライトバックキャッシングとライトスルーキャッシングの違いは?
-
[解決済み] Memcached vs. Redis? [クローズド]
-
[解決済み] Redisですべてを削除するには?
-
[解決済み] Redisを使用してパターンに一致するキーをアトミックに削除する方法
-
[解決済み] Redisキャッシュとメモリ直接使用との比較
-
[解決済み] キャッシュとメモライゼーションの違いは何ですか?
-
[解決済み] Angular 2のサイトでブラウザキャッシュを防ぐには?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】IISで静的リソースのHTTPヘッダーに有効期限や最大年齢を設定する方法
-
[解決済み] TLBシュートダウンとは何ですか?
-
[解決済み] コンフリクトミスとキャパシティミスの違いについて
-
[解決済み] キャッシュとキャッシュヒット/ミスについていくつか質問があります。
-
[解決済み] フラッシュ・トゥ・ディスク」とはどういう意味ですか?
-
[解決済み] ライトバックキャッシングとライトスルーキャッシングの違いは?
-
[解決済み] Redisキャッシュとメモリ直接使用との比較
-
[解決済み] Notepad++のキャッシュファイルの場所
-
[解決済み] Redis: 配列やソートされたセットの要素を失効させることは可能か?
-
[解決済み] Angular 2のサイトでブラウザキャッシュを防ぐには?