redis keysとscanコマンドの違いについて説明します。

4087 ワード

redis keysとscanの違い
redisのkeysコマンドは、通常は関連keyを削除するために使用されますが、このコマンドには数百万以上のkeysがあると、実行速度が遅くなり、さらに致命的には、このコマンドはredis多重化されたioマスタスレッドをブロックします。このスレッドがブロックされている間、他のコマンドはredisサーバーに送られます。一連のカスケード反応を引き起こし、瞬間的に該当するカードトンがタイムアウトなどの問題を引き起こすため、生産環境ではkeysと同様のコマンドsmbersを使用禁止すべきで、この時間の複雑さはO(N)であり、主スレッドをブロックする命令であり、非常に危険である。
もし生産環境において、keyを検索して削除する必要があるなら、keyの代わりにscanコマンドを使うべきです。scanもO(N)の複雑さであり、通過検索keyのコマンドをサポートしています。異なるkeysは、ラベルがロットで反復してデータを返すので、メインスレッドをブロックしなくてもいいです。
scan:漸進的なエルゴードキー

SCAN cursor [MATCH pattern] [COUNT count]
scanパラメータは、3つのパラメータ(6.0後にtypeパラメータを追加し、公式文書を参照)を提供し、最初はcursor整数値(hashバケツのインデックス値)、2番目はkeyの正則モード、3番目は巡回のkeyの数(基準値、1次エルゴードの数は一定ではない)であり、条件に合致する結果の数ではない。
最初のパスは、cursor値が0であり、その後、戻り値の最初の整数値を次の巡回のcursorとします。
戻るまで巡回していたcursor値は0で終了します。
使用例は以下の通りです。

運行結果からいくつかの問題が見られます。
スキャンのcountを10と指定しましたが、実際にスキャンした数は10とは限らないです。
彼は多分繰り返しkeyを遍歴します。
ここで説明します。なぜスキャンした数量は10とは限らないですか?これはtchが実際にフィルタの役割に相当するため、scanは実は先に10個の元素をスキャンして、それからpatternによって濾過しますと、残りの条件を満たす要素は10個もないかもしれません。一つもないかもしれません。
また、scanの過程でキーの変化(追加、削除、修正)があれば、新しいキーは遍歴されないかもしれません。つまり、scanはすべてのキーを遍歴することが保証できません。これは私たちが開発する時に考慮しなければなりません。
詳細については、例えば、なぜ追加されたキーは遍歴されないかもしれません。後はもっと深くredisの下のデータ構造を勉強しました。
つまり、redisの大数量操作については、正確にはできません。

補足:redisぼんやりとkeysとscanの比較と使い方を調べます。
一、keys
1、文法

keys pattern 
2、説明
disであいまいなクエリが許可されているのは、3つのワイルドカードです。それぞれ:*,?[]
*:任意の複数の文字を配合します。
?:1文字に共通
[]:括弧内の任意の文字を配合します。
3、操作

192.168.230.21:6379[2]> set hello 1
OK
192.168.230.21:6379[2]> set word 1
OK
192.168.230.21:6379[2]> set hellp 1
OK
192.168.230.21:6379[2]> set ahellog 1
OK
192.168.230.21:6379[2]> set hellog 1
OK
192.168.230.21:6379[2]> keys *
1) "hello"
2) "hellog"
3) "hellp"
4) "word"
5) "ahellog"
192.168.230.21:6379[2]> keys *hell*
1) "hello"
2) "hellog"
3) "hellp"
4) "ahellog"
192.168.230.21:6379[2]> keys hell*
1) "hello"
2) "hellog"
3) "hellp"
//         ,         
192.168.230.21:6379[2]> keys hell?
1) "hello"
2) "hellp"
//         ,          
192.168.230.21:6379[2]> keys hell??
1) "hellog"
//        ,          p t y      
192.168.230.21:6379[2]> keys hell[pty]
1) "hellp"
192.168.230.21:6379[2]> 
二、scan
1、文法

SCAN cursor [MATCH pattern] [COUNT count]
2、説明
scanラベルMATCH<与えられたモードにマッチする要素>countは、反復毎に返される要素の数であり、SCANコマンドは、インクリメンタルループであり、呼び出し毎に、ほんの一部の要素だけを返す。scanは2つの結果を返します。1つは次の遍歴のためのラベルです。一つは結果集です。
SCANコマンドは、各起動後にユーザに新しいビーコンを返します。ユーザは、次の反復時にこの新しいビーコンをSCANコマンドのビーコンパラメータとして使用する必要があります。これによって前の反復プロセスを継続します。
SCANコマンドのラベルパラメータが0に設定されると、サーバは新しい反復を開始し、サーバがユーザに0の値を返したときには、反復が終了したことを示す。
3、操作

192.168.230.21:6379[2]> keys *
1) "hello"
2) "hellog"
3) "hellp"
4) "word"
5) "ahellog"
192.168.230.21:6379[2]> scan 0 match *ll* count 2
1) "5"
2) 1) "hellp"
 2) "hello"
192.168.230.21:6379[2]> scan 5 match *ll* count 2
1) "0"
2) 1) "hellog"
 2) "ahellog"
192.168.230.21:6379[2]> 
三、性能対比
1、私達はredisの中のあるdbの中のすべてのデータを取得して`keys`のこのような命令で実現することができます。しかし、一つの問題があります。このようにすれば、データ量が多い場合、効率が良くないです。
2、Keysの曖昧さが合っていますので、実際に使う時は無視してください。KeysはRedisロックを誘発し、RedisのCPU占有を増加させるため、状況は非常に悪い。データが膨大であれば、数秒かそれ以上は必要かもしれません。生産サーバに数秒ロックするのは絶対に災難です。
3、新しいコマンドSCANが現れて、大きなデータ量のデータベースをkeysで遍歴することによって、サーバがブロックされる状況を解決してくれます。毎回データの一部だけが便利で、毎回の操作に対応する時間の複雑さはO(1)です。
以上は個人の経験ですので、参考にしていただければと思います。間違いがあったり、完全に考えていないところがあれば、教えてください。