Redis KEYSコマンドを無差別に使用することはできません。オンラインの代わりに、SCANを使用できます。

KEYSコマンド

時間計算量:O(N)、Redisのキー名と指定されたパターンの長さが制限されていると仮定すると、Nはデータベース内のキーの数です。

Redis Keysコマンドは、特定のパターンに一致するすべてのキーを見つけるために使用されます

この操作の時間計算量はO(N)ですが、一定時間は非常に低くなっています。たとえば、通常のラップトップでRedisを実行すると、100万個のキーをスキャンするのに40ミリ秒しかかかりません。

コマンドフォーマットKEYSパターン

警告:実稼働環境では、KEYSコマンドを使用して十分に注意してください。大規模なデータベースでコマンドを実行すると、パフォーマンスに影響を与える可能性があります。このコマンドは、キースペースレイアウトの変更など、デバッグや特殊な操作に適しています。コードでKEYSを使用しないでください。キースペースにキーのサブセットが必要な場合は、SCANまたはセットの使用を検討してください。

サポートされているマッチングパターン:

  • h?lloはhello、hallo、hxlloに一致します

  • h * lloはhlloとheeeelloに一致します

  • h [ae] lloはhelloとhalloに一致しますが、hilloには一致しません

  • h [^ e] lloはhallo、hbllo、…はhelloと一致しません

  • h [ab] lloはhalloとhblloに一致します

\を使用して、一致させたい特殊文字をエスケープします。

バックグラウンド

1. Redisはシングルスレッドであり、そのすべての操作はアトミックであり、並行性によるデータ例外はありません

2.時間のかかるRedisコマンドの使用は非常に危険です。1つのスレッドだけで多くの処理時間がかかり、すべてのリクエストの速度が低下します。

シーン

    KEYSコマンドを本番環境で実行する場合、Redisはシングルスレッドであるため、データベースデータの増加に伴い、KEYSコマンドのパフォーマンスはますます遅くなります。KEYSコマンドを使用すると、大量のデータを消費します。単一スレッドでの処理時間、Redisブロッキングが発生し、RedisのCPU占有率が増加すると、すべてのリクエストが遅くなり、Redisが配置されているサーバーがダウンする可能性があります。状況は非常に悪いです。実際の本番環境とアプリケーションでは無視してください。処理する。Redisが10秒を超えてブロックされている場合、クラスターシナリオがあると、クラスターがRedisに障害が発生したと判断し、フェイルオーバーを実行する可能性があると想像してください。

    すべてのスレッドがRedisからデータを取得できない場合、状況が深刻なときにアプリケーションで雪崩が発生する可能性があります。すべてのスレッドがデータベースにアクセスしてデータを瞬時にフェッチすると、データベースがダウンします。

その他の危険な命令

時間計算量がO(N)のコマンドを見つけた場合は、本番環境で何気なく使用しないように注意する必要があります。たとえば、hgetall、lrange、smembers、zrange、sinterなどのコマンドは使用できませんが、これらのコマンドの時間計算量はO(N)です。これらのコマンドを使用するには、Nの値を指定する必要があります。指定しないと、キャッシュがクラッシュします。発生します

1. flushdbコマンドは、現在のデータベース内のすべてのキーをクリアするために使用されます

2.fluxhallコマンドを使用してRedisサーバー全体のデータをクリアします(すべてのデータベースのすべてのキーを削除します)

3.構成クライアントが接続された後、サーバーを構成できます

危険なコマンドを無効にする方法

redis.confのSECURITYアイテムに、次の設定を追加して、指定したコマンドを無効にします。

rename-command FLUSHALL ""
rename-command FLUSHDB  ""
rename-command CONFIG   ""
rename-command KEYS ""

さらに、fluxhallコマンドの場合、構成ファイルでappendonly noを設定する必要があります。そうしないと、サーバーを起動できません。

コマンドを保持したいが使いにくい場合は、コマンドの名前を次のように変更できます。

rename-command CONFIG b840fc02d524045429941cc15f59e41cb7be6c52

ヒント: AOFファイルに記録されたコマンドまたはスレーブサーバーに転送されたコマンドの名前を変更すると、問題が発生する可能性があります。

改善のための提案

1.そのような要求がある場合は、さまざまなキー値をさまざまなセットに格納したり、分類ごとにインデックスを作成したりするなど、自分でキー値にインデックスを付けることができるため、データをすばやく取得できますが、これには明らかな欠点は、貴重なスペースの浪費であるため、それでも合理的に検討する必要があります。もちろん、通常のキー値、開始値と終了値などを保存する方法も見つけることができます。

2. scanコマンドは、改良されたキーおよびsmembersコマンドにも使用できます。

SCANコマンド

Redisはバージョン2.8以降のscanコマンドをサポートしており、Redisレコードをバッチでスキャンするために使用できます。これにより、クエリ全体で消費される合計時間が確実に長くなり、サービスの使用に影響しますが、redisサービスのフリーズには影響しません。 SCANコマンドの基本的な使用法は次のとおりです。

コマンドフォーマットSCANカーソル[MATCHパターン] [COUNTカウント]

SCANコマンドは3つのパラメーターを提供します。1つ目はカーソル、2つ目は一致する規則性、3つ目は単一トラバーサルのスロットです。

SCANコマンドとそれに関連するSSCAN、HSCAN、およびZSCANコマンドは、要素のコレクションを段階的に反復するために使用されます。

  • SCANコマンドは、現在のデータベースのデータベースキーを反復処理するために使用されます。

  • SSCANコマンドは、コレクションキーの要素を反復するために使用されます。

  • HSCANコマンドは、ハッシュキーのキーと値のペアを反復するために使用されます。

  • ZSCANコマンドは、順序セット内の要素(要素メンバーと要素スコアを含む)を反復するために使用されます。

上記の4つのコマンドはすべて増分反復をサポートしており、実行されるたびに少数の要素しか返さないため、これらのコマンドは、KEYSコマンドとSMEMBERSコマンドによって引き起こされる問題なしに実稼働環境で使用できます。 KEYSコマンドを使用して大規模なデータベースを処理する場合、またはSMEMBERSコマンドを使用して大規模なキーのセットを処理する場合、サーバーが数秒間ブロックされることがあります。

ただし、増分反復コマンドには欠点がないわけではありません。たとえば、SMEMBERSコマンドは、現在設定されているキーに含まれているすべての要素を返すことができますが、SCANなどの増分反復コマンドの場合、キーがインクリメントされるため、キーはプロセスで変更される可能性があります。反復型のため、増分反復コマンドは、返される要素について限定的な保証しか提供できません。

SCAN、SSCAN、HSCAN、およびZSCANの作業方法は非常に似ているため、これら4つのコマンドを一緒に紹介しますが、次の点に注意してください。

  • SSCANコマンド、HSCANコマンド、およびZSCANコマンドの最初のパラメーターは、常にデータベースキーです。

  • SCANコマンドは、現在のデータベース内のすべてのデータベースキーを反復処理するため、最初のパラメーターにデータベースキーを指定する必要はありません。

SCANコマンドの基本的な使用法

SCANコマンドはカーソルベースのイテレータです。SCANコマンドを呼び出すたびに、新しいカーソルがユーザーに返されます。ユーザーは、次の反復でこの新しいカーソルをSCANコマンドのカーソルパラメーターとして使用する必要があります。前の反復プロセスを続行します。

SCANコマンドのカーソルパラメータが0に設定されている場合、サーバーは新しい反復を開始し、サーバーが値0のカーソルをユーザーに返す場合、反復が終了したことを意味します。

以下は、SCANコマンドの反復プロセスの例です。

redis 127.0.0.1:6379> scan 0
1) "17"
2)  1) "key:12"
    2) "key:8"
    3) "key:4"
    4) "key:14"
    5) "key:16"
    6) "key:17"
    7) "key:15"
    8) "key:10"
    9) "key:3"
    10) "key:7"
    11) "key:1"

redis 127.0.0.1:6379> scan 17
1) "0"
2) 1) "key:5"
   2) "key:18"
   3) "key:0"
   4) "key:2"
   5) "key:19"
   6) "key:13"
   7) "key:6"
   8) "key:9"
   9) "key:11"

上記の例では、最初の反復でカーソルとして0が使用されます。これは、新しい反復を開始することを意味します。

2番目の反復では、最初の反復で返されたカーソルが使用されます。つまり、コマンドは最初の要素-17の値を返します。

上記の例からわかるように、SCANコマンドの応答は、2つの要素を含む配列です。最初の配列要素は次の反復の新しいカーソルであり、2番目の配列要素は配列です。この配列にはすべての要素が含まれます。繰り返されています。

SCANコマンドの2回目の呼び出しで、コマンドはカーソル0を返しました。これは、反復が終了し、コレクション全体が完全にトラバースされたことを意味します。

0をカーソルとして新しい反復を開始し、コマンドがカーソル0を返すまでSCANコマンドを呼び出し続けます。このプロセスを完全な反復と呼びます。

SCANコマンドの保証(保証)

SCANコマンド、および完全なトラバーサルの場合のその他の増分反復コマンドは、ユーザーに次の保証を提供できます。完全なトラバーサルの開始から完全なトラバーサルの終了まで、データに常に存在していたすべての要素セットは完全にトラバースされて返されます。これは、トラバーサルの開始から終了までトラバースされたデータセットに要素が存在する場合、SCANコマンドは常にこの要素を特定のユーザーに返すことを意味します。反復。

ただし、インクリメンタルコマンドはカーソルのみを使用して反復ステータスを記録するため、これらのコマンドには次の欠点があります。

  • 同じ要素が複数回返される場合があります。重複する要素を処理するタスクはアプリケーションプログラムに任されています。たとえば、反復によって返された要素を、安全に複数回繰り返すことができる操作にのみ使用することを検討できます。

  • 要素が反復プロセス中にデータセットに追加された場合、または反復プロセス中にデータセットから削除された場合、この要素が返される場合と返されない場合があります。これは未定義(未定義)です。

実行ごとにSCANコマンドによって返される要素の数

増分反復コマンドは、各実行が指定された数の要素を返すことを保証するものではありません。

インクリメンタルコマンドはゼロ要素を返すこともありますが、コマンドによって返されるカーソルが0でない限り、アプリケーションは反復を終了として扱うべきではありません。

ただし、コマンドによって返される要素の数は、常に特定のルールに準拠しています。実際には、次のようになります。

  • 大規模なデータセットの場合、増分反復コマンドは毎回最大で数十の要素を返す可能性があります

  • 十分に小さいデータセットの場合、データセットの基になる表現がエンコードされたデータ構造(小さいコレクションキー、小さいハッシュキー、および小さい順序付きコレクションキーに適用可能)である場合、増分反復コマンドデータセット内のすべての要素は次のようになります。 1回の呼び出しで返されました。

最後に、ユーザーは、増分反復コマンドによって提供されるCOUNTオプションを使用して、各反復で返される要素の最大値を指定できます。

COUNTオプション

インクリメンタル反復コマンドは、反復ごとに返される要素の数を保証するものではありませんが、COUNTオプションを使用して、コマンドの動作をある程度調整することができます。

基本的に、COUNTオプションの機能は、各反復でデータセットから返される要素の数を反復コマンドにユーザーに指示させることです。

COUNTオプションは、増分反復コマンドのヒントにすぎませんが、ほとんどの場合、このヒントは効果的です。

  • COUNTパラメーターのデフォルト値は10です。

  • 十分な大きさのデータベース、コレクションキー、ハッシュキー、またはハッシュテーブルによって実装された順序付きコレクションキーを反復する場合、ユーザーがMATCHオプションを使用しない場合、コマンドによって返される要素の数は通常、COUNTで指定された数と同じです。オプション、またはCOUNTオプションで指定された数よりわずかに多い。

  • 整数のセット(intset、整数値のみで構成される小さなセット)または圧縮リスト(ziplist、異なる値で構成される小さなハッシュ、または小さな順序のセット)を反復する場合、incremental繰り返しコマンドは通常、指定された値を無視しますCOUNTオプションを使用して、最初の反復でデータセットに含まれるすべての要素をユーザーに返します。

すべての反復で同じCOUNT値が使用されるわけではありません

ユーザーは、前の反復から次の反復に返されたカーソルを使用することを覚えている限り、各反復で必要に応じてCOUNTの値を変更できます。

MATCHオプション

KEYSコマンドと同様に、インクリメンタル反復コマンドもglobスタイルのパターンパラメーターを提供できるため、コマンドは指定されたパターンに一致する要素のみを返します。これは、指定されたMATCHパラメーターを渡して達成できます。

以下は、反復にMATCHオプションを使用する例です。

redis 127.0.0.1:6379> sadd myset 1 2 3 foo foobar feelsgood
(integer) 6

redis 127.0.0.1:6379> sscan myset 0 match f*
1) "0"
2) 1) "foo"
   2) "feelsgood"
   3) "foobar"

要素のパターンマッチングは、データセットからコマンドが取得された後、要素がクライアントに返される前の期間に実行されることに注意してください。したがって、反復データセットに要素が少ない場合は、パターンに一致する場合、反復コマンドは複数の実行で要素を返さない場合があります。

以下は、この状況の例です。

redis 127.0.0.1:6379> scan 0 MATCH *11*
1) "288"
2) 1) "key:911"

redis 127.0.0.1:6379> scan 288 MATCH *11*
1) "224"
2) (empty list or set)

redis 127.0.0.1:6379> scan 224 MATCH *11*
1) "80"
2) (empty list or set)

redis 127.0.0.1:6379> scan 80 MATCH *11*
1) "176"
2) (empty list or set)

redis 127.0.0.1:6379> scan 176 MATCH *11* COUNT 1000
1) "0"
2)  1) "key:611"
    2) "key:711"
    3) "key:118"
    4) "key:117"
    5) "key:311"
    6) "key:112"
    7) "key:111"
    8) "key:110"
    9) "key:113"
   10) "key:211"
   11) "key:411"
   12) "key:115"
   13) "key:116"
   14) "key:114"
   15) "key:119"
   16) "key:811"
   17) "key:511"
   18) "key:11"

ご覧のとおり、上記の反復のほとんどは要素を返しません。

最後の反復では、COUNTオプションのパラメーターを1000に設定して、コマンドがこの反復でより多くの要素をスキャンするように強制し、コマンドがより多くの要素を返すようにします。

複数の反復を同時に実行する

同時に、同じデータセットで反復するクライアントはいくつでも存在できます。クライアントは反復ごとにカーソルを渡し、反復後に新しいカーソルを取得する必要があります。したがって、このカーソルには反復的なすべての状態が含まれます。 、サーバーは反復のために状態を記録する必要はありません。

途中で反復を停止します

反復のすべての状態がカーソルに格納され、サーバーが反復の状態を格納する必要がないため、クライアントはサーバーに通知せずに反復を途中で停止できます。

途中で何度も繰り返し停止しても問題ありません。

増分反復に間違ったカーソルを使用する

壊れた、負の、範囲外、またはその他の異常なカーソルを使用して増分反復を実行しても、サーバーがクラッシュすることはありませんが、コマンドの未定義の動作が発生する可能性があります。

未定義の動作は、インクリメンタルコマンドによる戻り値への保証が真ではなくなる可能性があることを意味します。

2種類のカーソルのみが有効です。

1.新しい反復を開始するとき、カーソルは0でなければなりません。

2.増分反復コマンドの実行後に返される反復プロセスを続行するために使用されるカーソル。

反復終了の保証

増分反復コマンドで使用されるアルゴリズムは、データセットのサイズが制限されたときに反復が停止することを保証するだけです。つまり、反復データセットのサイズが増え続けると、増分反復コマンドが完全に完了することはありません。反復。

データセットが大きくなり続けると、データセット内のすべての要素にアクセスするために、より多くの作業を行う必要があることが直感的にわかります。反復を終了できるかどうかは、ユーザーが反復をより速く実行するかどうかによって異なります。データセットはより速く成長します。

時間計算量:

    インクリメンタル反復コマンドの各実行の複雑さはO(1)であり、データセットの完全な反復の複雑さはO(N)です。ここで、Nはデータセット内の要素の数です。

戻り値:

    SCANコマンド、SSCANコマンド、HSCANコマンド、およびZSCANコマンドはすべて、2つの要素を含むマルチバルクを返します。応答:応答の最初の要素は、文字列で表される符号なし64ビット整数(カーソル)であり、2番目の要素は応答これは別のマルチバルク応答です。このマルチバルク応答には、今回繰り返される要素が含まれています。

    SCANコマンドによって返される各要素はデータベースキーです。

    SSCANコマンドによって返される各要素はセットメンバーです。

    HSCANコマンドによって返される各要素はキーと値のペアであり、キーと値のペアはキーと値で構成されます。

    ZSCANコマンドによって返される各要素は、順序集合要素です。順序集合要素は、メンバーとスコアで構成されます。

その他の使用法については、RedisSCANコマンドを参照してください。

http://doc.redisfans.com/key/scan.html

 

参照:

https://redis.io

https://www.dazhuanlan.com/2019/12/17/5df832fd189f6

おすすめ

転載: blog.csdn.net/JineD/article/details/111282163