Webアプリケーションを実行していて、キャッシングのためにmemcachedからredis(2.4)に切り替えました。現在、redisのパフォーマンスに少しがっかりしています。 Redisは同じサーバー上で実行されており、非常に単純なGETおよびSET操作のみを使用しています。キャッシュされた値を頻繁に使用する一部のリクエストでは、最大300のGETリクエストでredisを実行できますが、それらのリクエストには最大150ミリ秒かかります。約200,000のアクティブなキーがあり、1秒あたり約1,000のredisリクエストがあります。ディスクio、ram、cpuには問題はありません。既存のコードのため、redisリクエストを単にグループ化することはできません。 Memcachedは約4倍高速になりました。 redisで気に入っている点は、キャッシュのウォーミングが不要であり、将来、より高度なデータストア機能を使用できるようになることです。 redisはmemcachedと同様のパフォーマンスを期待しています。つまり、基本的にデフォルトの構成である構成で何かを見逃した可能性があります。
redisパフォーマンスチューニングのベストプラクティスを知っていますか?
最初に、 Redisベンチマークページ を読むことをお勧めします。 Redisをチューニングするためにチェックする主要なポイントの良い要約を提供します。
パイプライン処理を使用しない場合でも、150ミリ秒で300回のGETは効率的ではありません。つまり、平均レイテンシは500 usです。ただし、実際にはオブジェクトのサイズによって異なります。オブジェクトが大きいほど、待機時間が長くなります。私の非常に古い2 GHz AMDボックスで、小さなオブジェクト(数バイト)の150 usレイテンシを測定できます。
Redisインスタンスの平均レイテンシをすばやく確認するには、以下を使用できます。
$ redis-cli --latency
このオプションを取得するには、必ず最新のRedisバージョン(2.4ではない)を使用してください。注:2.4はかなり古いものです。Redis2.6を使用してください。必要に応じて独自のRedisバージョンをコンパイルしてください。これは非常に簡単です。
ベンチマークをすばやく実行してレイテンシを調査するには、以下を起動します。
$ redis-benchmark -q -n 10000 -c 1 -d average_size_of_your_objects_in_bytes
ユニークな接続で実行され、パイプライン処理がないため、レイテンシはスループットから推定できます。これらのベンチマークの結果を、アプリケーションで測定した数値と比較してみてください。
確認したいポイントがいくつかあります。
Memcachedの方が良いのはなぜですか?まあ、単一のmemcachedインスタンスは確かにスケーラブルであり、複数のスレッドで実行される可能性があるため、単一のRedisインスタンスよりも応答性が高い場合があります。 Redisは高速ですが、シングルスレッドです。すべてのコマンドの実行がシリアル化されます。そのため、接続中にコマンドが実行中の場合、他のすべてのクライアントは待機する必要があります。特定のコマンドのレイテンシが悪いと、保留中のすべてのコマンドにも影響します。一般に、低スループットでは、パフォーマンスは同等です。
1000 q/s(Redisまたはmemcached標準による低スループット)では、問題はクライアント側(つまり、クライアントライブラリの選択、接続/切断など)にある可能性が高いです。 Redisサーバー自体。
最後に、HTTPリクエストごとに多数のRedisクエリを生成する場合は、Redisに送信するコマンド pipelining を可能な限り考慮してください。これは、効率的なRedisアプリケーションを開発するための重要なポイントです。
アプリケーションサーバーがRedisと同じボックス上にある場合、TCPループバックの代わりにUNIXドメインソケットを使用してRedisに接続することもできます。これにより、パフォーマンスがわずかに向上します(最大50%のスループット向上)。パイプライン処理は使用されません)。
RedisがOSスワップメモリを使用しているかどうかを確認します。その場合、レイテンシが増加します。確認するには、ここで「スワッピングによって引き起こされるレイテンシ」を検索します。 http://redis.io/topics/latency
サーバーハードウェアがNUMA対応である場合は、numactlを使用してredis-serverを開始することをお勧めします。 NUMAを使用したredis-serverで開始する場合は、sysctlでゾーン再利用モード(vm.zone_reclaim_mode = 0)をオフにすることを忘れないでください。
Luaスクリプト内で300 GETリクエストをスクリプト化してみてください。クライアントコードがRedisに対してローカルで実行されている場合でも、TCP/IPスタックへのタッチ時の時間を節約できるため、より速く動作するはずです。