編集者が担当するアプリケーションは管理バックグラウンドアプリケーションであり、権限管理にはShiroフレームワークを使用しています複数のノードがあるため分散セッションを使用する必要があるため、Redisを使用していますセッション情報を保存するために使用されます。
Shiro は Redis ストレージ セッション コンポーネントを直接提供していないため、Afan は Github のオープン ソース コンポーネントである hiro-redis を使用する必要がありました。
Shiro フレームワークはセッションが有効かどうかを定期的に確認する必要があるため、Shiro の最下層は SessionDAO#getActiveSessions
を呼び出してすべてのセッション情報を取得します。
そして hiro-redis
はたまたま SessionDAO
インターフェイスを継承しており、最下層は keys
コマンドを使用してすべての Session を検索します## Redis に保存されます。#key。
public Set<byte[]> keys(byte[] pattern){ checkAndInit(); Set<byte[]> keys = null; Jedis jedis = jedisPool.getResource(); try{ keys = jedis.keys(pattern); }finally{ jedis.close(); } return keys; }
shiro-redis を最新バージョンにアップグレードします。
hiro-redis は、
keys の代わりに
scan コマンドを使用して、この問題を解決します。
public Set<byte[]> keys(byte[] pattern) { Set<byte[]> keys = null; Jedis jedis = jedisPool.getResource(); try{ keys = new HashSet<byte[]>(); ScanParams params = new ScanParams(); params.count(count); params.match(pattern); byte[] cursor = ScanParams.SCAN_POINTER_START_BINARY; ScanResult<byte[]> scanResult; do{ scanResult = jedis.scan(cursor,params); keys.addAll(scanResult.getResult()); cursor = scanResult.getCursorAsBytes(); }while(scanResult.getStringCursor().compareTo(ScanParams.SCAN_POINTER_START) > 0); }finally{ jedis.close(); } return keys; }
keys コマンドによって他のコマンドの実行が遅くなるのはなぜですか?
Keysコマンドクエリは非常に遅いのでしょうか?
Scan コマンドでは問題がないのはなぜですか?
keys 命令によって他のコマンドの実行が遅くなるのはなぜですか?
Keys コマンド クエリはなぜ非常に遅いのでしょうか?
keys コマンドは、指定されたパターン
pattern に一致するすべての Redis キーを返す必要があります。この目的を達成するために、Redis は辞書
を走査する必要があります。 ht[ 0]ハッシュ テーブルの基礎となる配列。今回の複雑さは
『O(N)』 (N は Redis のキーの数) です。
keys を使用してすべてのキーをクエリします。このクエリは約 10 秒間ブロックされます。 . .
eval "for i=1,100000 do redis.call('set',i,i+1) end" 0
ここでは、Afan は Redis をデプロイするために Docker を使用しているため、パフォーマンスは若干劣る可能性があります。SCAN 原則最後に 3 番目の質問を見てみましょう。なぜ
scan コマンドには問題がないのでしょうか?
scan コマンドがブラック テクノロジである
「カーソルベースの反復子」 を使用しているためです。
scan コマンドが呼び出されるたびに、Redis は新しいカーソルと特定の数のキーをユーザーに返します。次回も引き続き残りのキーを取得したい場合は、このカーソルを scan コマンドに渡して、前の反復プロセスを続行する必要があります。
scan コマンドはページングを使用して Redis をクエリします。
scan このコマンドは、カーソルを使用して完全なクエリを複数回に巧みに分割し、複雑さを軽減します。クエリの支出。
scan コマンドの時間計算量は
keys と同じで、どちらも
「O(N)」 ですが、 scan このコマンドは少数のキーを返すだけでよいため、実行速度は非常に速くなります。
scan コマンドは
keys の欠点を解決しますが、他のいくつかの欠点も引き起こします。
反復プロセス中に、Redis に追加される要素または削除される要素が返される場合もあれば、返されない場合もあります。
上記の欠陥は、開発時に考慮する必要があります。
scan に加えて、redis には増分反復のための他のコマンドがいくつかあります:
sscan: use 反復に使用されます。現在のデータベース内のデータベース キー。
smembers ブロックされる可能性がある問題を解決するために使用されます。
#hscan コマンドは、ハッシュ キーを反復するために使用されます。 キー-value ペアは、可能性のあるブロッキング問題
hgetall を解決するために使用されます。
zscan: このコマンドは、順序付きセット内の要素 (要素メンバーと要素スコアを含む) を反復するために使用され、
zrange を生成するために使用されます。 ブロッキングの問題が発生する可能性があります。
以上がRedisコマンドの使用例分析の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。