2015-09-16 3 views
16

official Redis documentationを含むいくつかのソースは、KEYSコマンドを使用するとブロックされる可能性があるため、本番環境では悪い考えです。データセットのおおよそのサイズがわかっている場合、SCANKEYSよりも利点がありますか?SCAN対RedisのKEYSパフォーマンス

例えば、data:number:Xという形式の100個以下のキーを持つデータベースを考えてみましょう。ここで、Xは整数です。これらのすべてを取得したい場合は、コマンドKEYS data:number:*を使用します。これはSCAN 0 MATCH data:number:* COUNT 100を使用するよりも大幅に遅くなりますか?あるいは、このような状況では2つのコマンドが本質的に同等ですか? SCANは、予期せず大きなセットが返されるシナリオに対して保護するため、KEYSよりも好ましいと言えるでしょうか?

+0

ページネーションを使用していない場合は、パフォーマンスの差はありません。 –

答えて

18

Redisは単一のスレッドを使用してコマンドを処理するため(つまり、コマンドが実行されている間は、他のすべてのコマンドが実行されるまで待つ必要があるため)、現在のコマンドの実行は他のすべてのコマンドには影響しません。

keysまたはscanの場合、Redisをブロックするのに数ミリ秒かかるとI/O全体が大幅に減少します。

これは、開発目的でkeysを使用し、運用環境でscanを使用する主な理由です。

OPは言った:

「キーまたはスキャンはあなたに類似または同一のパフォーマンスを提供するかもしれませんが あなたのケースでのみ実行され、Redisのを阻止するいくつかのミリ秒を大幅にI/O全体的な減少 ます。」 - この文は、1つのコマンドがRedisをブロックする を示しているようですが、もう1つはコマンドを受け入れないため、 にはなりません。私がKEYSへの私の呼び出しから100の結果が保証されている場合、 はSCANより悪いですか?なぜあなたは1つのコマンドがより多くのブロックであると感じていますか? ブロックする傾向がありますか?

検索が改ページできる場合は、違いがあります。 1回のパスで100個のキーを取得するのは、ページネゴシエーションを実装して100個のキー(10×10(50,50))を取得するよりも強制的に実行されるわけではありません。 この非常に小さな割り込みによって、アプリケーション層が送信した他のコマンドをRedisで処理できるようになります。

これらのコマンドは、インクリメンタル反復を可能にするので、呼び出しごとの要素だけ 小さな数を返す、彼らはKEYSまたはSMEMBERSのようなコマンドの欠点なしに生産 で使用することができます:Redisの公式ドキュメントはこのことについて言っていることを参照してください。それは、キーまたは要素

の 大きなコレクションに対して呼ばれる長い時間(さらには数秒) サーバーをブロックすることがあります。

+0

非常に真です。しかし、100個のキーでは、実際的な違いはありません。また、 'SCAN'の' COUNT'引数は指令ではなくヒントに過ぎないことに注意してください。 –

+2

@ItamarHaberところで私は「これは決して起こらない」ということに頼るのではなく、設計によって正しいアプローチでソリューションを設計するのが好きです。一方、グローバルなキースペースで 'keys'や' scan'が必要な場合は、データを保存してページにアクセスする方が良い解決策があるように思えるでしょうか? 'lrange'、' zrange':D –

+0

"キーやスキャンによって、あなたの場合に似たようなパフォーマンスが得られるかもしれませんが、数ミリ秒でRedisをブロックすると全体的なI/Oが大幅に減少します。 - この文は、1つのコマンドがRedisをブロックし、もう1つがRedisをブロックしていることを示しているようです。私が 'KEYS 'を呼び出した結果100点が保証されていれば、どのように' SCAN'よりも悪いですか?なぜあなたは1つのコマンドがブロックする傾向があると感じますか? – Jake

4

答えは、これらのコマンドは、インクリメンタル反復のため、呼び出しごとの要素のほんの数を返す、彼らはKEYSまたはSMEMBERSのようなコマンドの欠点なしに製造に使用することができます許可SCANドキュメントに

です大量のキーや要素の集合に対してサーバーが呼び出されたときにサーバーが長時間(数秒間)ブロックされる可能性があります。

ので、データの小さな塊を求めるのではなくマティアスFidemraizerが指摘したように、それの全体

はまた、RedisのはシングルスレッドであるとKEYSは、このように実行されるまでの動作のための任意の着信要求を遮断するブロッキング呼び出しで取得KEYSが行われます。

データが小さいかどうかにかかわらず、ベストプラクティスを適用することは決してありません。量はクライアントへのRedisから(IO)に転送されたバイト

+2

説明 - Redisのすべてのコマンドは、シングルスレッドなのでサーバー上でブロックしています。キーは、いくつかの操作で少量のキーを戻すのではなく、1回の操作ですべてのキーを取得しようとすると、長時間ブロックする可能性があります。 –

-2
  1. ありKEYS間には性能差がなく、ページネーション(count)以外の走査は改ページに制御されます。

  2. カウントオプションには独自の仕様がありますが、データが取得されない場合もありますが、スキャンカーソルがオンのため、次の反復でデータが取得されます。したがって、カウントオプションは、複数の往復時間を避けるために、最大200までの合理的な量でなければなりません。私はこの値はあなたのデータベース内のキーの総数に依存すると思います。

  3. LUA内のSCANをKEYSと比較すると、IOはありませんが、大きなコレクション全体が反復されるまで他の呼び出しをブロックしています。私はこれを試していない、私の推測です。

+0

あなたが議決権を行使しているときにあなたのコメントを書いて、私も学び、訂正します。 –

関連する問題