[Redis] の落とし穴 (1) - 「共通コマンド」

この記事では、Redis の一般的なコマンド、基になるデータ構造、メモリ管理、クラスタリング、およびその他の関連する概念について一定の理解が必要です. 関連する知識ポイントをすばやく学ぶために、Redis インタビューの質問の概要を表示することをお勧めします.

1 はじめに

おそらく、Redis を使用するとき、多かれ少なかれいくつかの「奇妙な」シーンに遭遇し、「落とし穴」を踏む可能性が高くなります。

  • 有効期限が設定されたキーは、最終的に有効期限が切れていません。
  • O(1)複雑さのコマンドを使用するSETBITと、OOM であることが判明しました。
  • キーをRANDOMKEYランダム。メイン スレッドはブロックされます。
  • 同じコマンドの場合、メイン ライブラリはデータを見つけることができませんが、スレーブ ライブラリはデータを見つけることができます。
  • スレーブ ライブラリがメイン ライブラリより多くのメモリを使用するのはなぜですか。

Redis のいくつかの一般的な問題に精通し、理解することで、問題をすばやく見つけて解決することができます. 並べ替えと並べ替えの後、著者はこれらの問題を大まかに 3 つの部分に分けます:

  1. 一般的なコマンドの落とし穴は何ですか?
  2. データ永続化の落とし穴は何ですか?
  3. マスターとスレーブのライブラリ同期にはどのような落とし穴がありますか?

2 共通コマンドのピットイン

最初に、「予期しない」結果になる可能性がある一般的に知られているコマンドをいくつか見てみましょう。

2.1 失効時間の偶発的な損失

SETこのコマンドは、Redis で最もよく使用されるコマンドである必要があります. 次のように、キー値を設定するだけでなく、キーの有効期限も設定できます:

127.0.0.1:6379> SET testkey val1 EX 60
OK
127.0.0.1:6379> TTL testkey
(integer) 59

ただし、コードの他の場所からキーを変更し、「有効期限」パラメーターを追加しない場合、キーの有効期限は「消去」されます。つまり、有効期限が切れることはありません

127.0.0.1:6379> SET testkey val2
OK
127.0.0.1:6379> TTL testkey  // key永远不过期了!
(integer) -1

Redis のメモリが増え続け、多くのキーに有効期限が設定されていて、後で有効期限が失われていることが判明した場合は、この理由が原因である可能性があります。

2.2 DEL ブロック Redis

キーを削除する必要がある場合、すぐにDELコマンドその時間の複雑さについて考えたことはありますか?

DEL コマンドを導入する際、Redis の公式ドキュメントでは次のように説明されています。キーの削除にかかる時間は、そのタイプに関連しています。

  • キーは文字列型で、DEL 時間の計算量は O(1) です。
  • キーは List、Hash、Set、および ZSet 型で、DEL時間計算量は O(M) です。ここで、M は要素の数です。

Redis の基本的なデータ構造を理解していれば、理解するのは難しくありません. したがって、List 、 Hash 、 Set 、および ZSet 型のキーを削除するDEL場合は、特に注意する必要があります.考えずに実行することはできません. 、次の方法で ** を削除する必要があります:* *

1) キー内の要素数を照会します。LLEN HLEN SCARD ZCARDコマンドます。

2) キー内の要素の数を決定します。少ない場合は直接削除できます。そうでない場合は、バッチで削除できます。

3)一括削除: LRANGE/HSCAN/SSCAN/ZSCAN + LPOP/RPOP/HDEL/SREM/ZREM 削除を実行します。

上記はコレクション型ですが、String型を直接削除するとこうならないのでしょうか?

明らかに、 Redis のメイン スレッドもブロックします. String 型のキーは、デフォルトで最大 512M のデータを格納できることがわかっています. Redis がオペレーティング システムにそのような大量のメモリを解放する場合、時間がかかるに違いありません.

メインスレッドがオンになっている場合、lazy-freeメカニズムか?

Redis がレイジー フリーをオンにしても、文字列型の bigkey を削除すると、バックグラウンド スレッドで実行される代わりにメイン スレッドで処理されます。したがって、Redis をブロックするリスクは依然として解決できません。

2.3 RANDOMKEY ブロック Redis

Redis は、メモリ内のキーをランダムに表示するコマンドを提供します: RANDOMKEY. このコマンドは Redis からキーを「ランダムに」取得します. randomと呼ばれますが、実行速度は思ったほど速くありません.

この問題を明確に説明するには、Redis の有効期限ポリシーを組み合わせる必要があります。Redis は、通常のクリーニング遅延クリーニングの組み合わせを使用して、期限切れのキーをクリーンアップします。

実行プロセスを見RANDOMKEYて: Redis がランダムにキーを取り出した後、まずキーの有効期限が切れているかどうかを確認します。キーの有効期限が切れている場合、Redis はそれを削除します。このプロセスは遅延クリーンアップです。しかし、クリーニング後に終了することはできません。Redis は、「無期限」のキーが見つかり、クライアントに返されるまで、このサイクルを繰り返さなければなりません。

しかし、ここに問題があります: Redis の多数のキーがこの時点で期限切れになっているが、それらが時間内にクリーンアップされていない場合、このサイクルは終了するまで長時間続き、この時間はクリーンアップに費やされます期限切れのキー + 期限切れでないキーを探します。その結果、RANDOMKEY実行時間が長くなり、Redis のパフォーマンスに影響します。

上記のプロセスは主に Matser ノードを対象としており、スレーブ ノードがRANDOMKEYコマンドと、問題はより深刻になります。主な理由は、スレーブが期限切れのキーを自分でクリーンアップしないためです。

キーの有効期限が切れそうになると、マスターはまずキーをクリーンアップして削除し、次にマスターとスレーブ ライブラリ間のデータの一貫性を確保するために、スレーブにキーを削除するように指示するDELコマンドます。 .

有効期限が切れているがクリーンアップされていない多数のキーが同じ Redis にある同じシナリオでは、 Slave で実行するRANDOMKEYときに。

1) スレーブが鍵をランダムに取り出して、有効期限が切れているかどうかを判断します。

2) キーの有効期限が切れていますが、スレーブはそれを削除しませんが、有効期限が切れていないキーをランダムに検索し続けます。

3) 多数のキーが期限切れになっているため、スレーブは条件を満たすキーを見つけることができず、この時点で「無限ループ」に陥ります。

つまり、スレーブで実行すると、RANDOMKEYRedis インスタンス全体がスタックする可能性があります。

これは実際には Redis のバグであり、5.0 まで修正されませんでした。Redis が提供する解決策は次のとおりです。

Slave で実行RANDOMKEYする、まず、インスタンス全体のすべてのキーに有効期限が設定されているかどうかを判断します. その場合、長時間修飾キーを見つけることを避けるために、 Slave は最大 100 回のみハッシュ テーブルを検索します、できるかどうかに関係なく、見つかった場合はループを終了します。すなわち、リトライの最大回数が増加する。

ここに画像の説明を挿入

そのため、Redis を使用していて「ジッターRANDOMKEY」が発生していることが判明した場合は、この理由が原因である可能性があります。

2.4 SETBIT が OOM を引き起こす

文字列の文字列を格納するだけでなく、多くの場合、String 型はビットマップ ビットマップとして使用できます。つまり、値を個々のビットに分割して使用します。

127.0.0.1:6379> SETBIT testkey 10 1
(integer) 1
127.0.0.1:6379> GETBIT testkey 10
(integer) 1

しかし、落とし穴があります: キーが存在しない場合、またはキーのメモリ使用量が少なく、操作したいオフセットが非常に大きい場合、Redis は「より大きなメモリ空間」を割り当てる必要があり、操作時間が長くなります。長く、パフォーマンスに影響を与えます。

ここに画像の説明を挿入

したがって、SETBITを使用、オフセットのサイズにも注意する必要があります.大きすぎるオフセットを操作すると、Redis がフリーズします。もちろん、削除の影響にも注意してください。

2.5 MONITOR が OOM を引き起こす

MONITORコマンドを実行すると、Redis は各コマンドをクライアントの「出力バッファー」に書き込み、クライアントはサーバーから返された結果をこのバッファーから読み取ります。

ここに画像の説明を挿入

ただし、Redis に対応する QPS が高い場合、これにより出力バッファのメモリが増加し続け、Redis のメモリ リソースを大量に占有します.マシンのメモリ リソースがたまたま不足した場合、Redis インスタンスはOOM になるリスクに直面します。

おすすめ

転載: blog.csdn.net/adminpd/article/details/127342475