Redisメモリの断片化の問題

インメモリデータベースとして、メモリスペースのサイズはRedisにとって非常に重要です。メモリが多いほど、より多くのデータが保存されます。しかし、あなたがそのような状況に遭遇したことがあるかどうかはわかりません。明らかに多くのスペースがありますが、メモリ使用量はあまり理想的ではありません。

なぜそのような状況があるのですか?この「奇妙な」事件を見てみましょう。


Redisのメモリ使用量を表示する

まず、Redisメモリの使用状況を知りたい場合は、関連情報を取得する必要があります。

Redisでメモリ関連の情報を表示するのは非常に簡単です。コマンドラインで入力するだけです。

info memory

あらゆる種類の関連データを見ることができます。ここでは、いくつかのより重要なパラメーターをリストします。
ここに画像の説明を挿入

used_memory:已经使用了的内存大小。
used_memory_rss:redis 物理内存的大小。
mem_fragmentation_ratio:内存碎片率。

注意すべきメモリフラグメンテーション率の名詞があり、現在のメモリ使用量を表すために使用できます。具体的な計算方法:
ここに画像の説明を挿入
メモリの断片化率については、通常、1〜1.5の間に保つのが最も合理的です。


メモリの断片化とは

メモリの断片化率を知っていると、メモリの断片化とは何ですか?

定義は次のとおりです。連続する空き領域の一部が適用される領域よりも小さいため、この領域は使用できません。これは、メモリ全体のメモリの断片化です。

例えば:

100MBの連続空きメモリスペースがあり、毎回30MBのメモリを申請するとします。その後、3回申請すると、このメモリには10MBの空き容量しかなく、4回目の申請は失敗します。他のスペースが解放されず、毎回要求されるスペースが10MBを超える場合、残りのスペースはメモリ全体のメモリの断片化です。
ここに画像の説明を挿入


メモリの断片化の原因

Redisで最も一般的に使用されるのは、データの書き込み、変更、および削除です。これらの操作は、実行後にある程度のメモリの断片化を引き起こします。

データ入力

Redisのメモリ割り当ては、固定サイズに従ってメモリ空間を分割します。割り当ての数を減らすために、Redisは、要求されたメモリの最も近い固定値に従って、対応するサイズのスペースを割り当てます。

Redisが8バイト、16バイト、32バイト、48バイトなどに従ってメモリを割り当てる場合、それはどういう意味ですか。18バイトのデータを保存する場合、Redisは32バイトを割り当てます(32は18に最も近い固定値であるため)。この時点で、データの書き込みに必要なメモリスペースが14バイト以内の場合、Redisは再度割り当てる必要はありません。

まるで箱が違うようです。荷物を詰めるには、一番近いサイズの箱を探す必要があります。しかし、入れてみると、まだまだ小さなものが入る余地があるので、箱を探す必要はありません。

ただし、この方法でスペースを割り当てると、ある程度のメモリの断片化が発生します。固定サイズの分割スペースは、ボリュームの異なるボックスと見なすことができ、各ボックスのスペースにはさまざまな程度の余剰があります。残りのスペースはメモリの断片化です。

データを変更する
キーと値のペアが変更されると、大きくなったり小さくなったりする可能性があり、それに応じて追加のスペースが必要になるか、未使用のスペースが解放されます。
ここに画像の説明を挿入
図に示すように、現在、A、B、Cはそれぞれ3、2、4バイトを占めています。Aを3バイトから2バイトに変更すると、この時点で1バイトのスペースが空になります。 1バイトのフラグメントである。

ここに画像の説明を挿入
データAを3バイトから4バイトに変更するとどうなりますか?このとき、データAの空間的連続性を維持するために、オペレーティングシステムはBを別の空間にコピーします。このとき、別の1バイトのフラグメントが表示されます。

データを削除する

変更されたデータを理解した後、データを削除することは理解しやすいです。上記の例でも、データBが削除されると、2バイトのスペースが解放されます。これにより、メモリ空間全体に対して2バイトのフラグメントが作成されます。
ここに画像の説明を挿入


メモリの断片化の危険

不思議に思うかもしれませんが、メモリの断片化はどのような害を及ぼす可能性がありますか?

それでも上のボックスで表しています。考えてみてください。これらのボックスを車に積み込んで持ち帰りたい場合、各ボックスには空きスペース(メモリフラグメント)があり、1回の実行の効率と費用対効果は非常に低くなります。同様に、Redisでは、フラグメントが多数存在するため、実際の使用率は低くなります。


メモリの断片化を解決する方法

転覆

最初の方法は非常に簡単で、それを倒して最初からやり直すだけです。あれはRedisは直接再起動しますそれが完了すると、メモリの電源がオフになるとすぐに全世界がきれいになります。しかし、この暴力的でトラブルを回避する方法には、多くの隠れた危険があります。

実稼働環境でこれを行う場合は、問題が発生しないように、事前に線香を燃やす必要があります。永続化を行っていない場合は、燃やさないでください。燃やしても意味がありません。永続性がある場合、回復時間は永続化されたファイルのサイズにも依存し、この段階ではサービスを提供できません。心配ですか?

スペースの交換

それで、それほど刺激的でない方法があります。

はい、Redisの上位バージョンは、メモリフラグメントをクリーンアップする方法を提供します。一言で言えば、それはスペースの交換です。

交換方法は?私たちの目的はメモリの断片化を排除することですが、使用済みのメモリデータを一緒に再配置することはできませんか?不連続な空間を連続的にしましょう、残りのスペースは、割り当てを続行します。

理解するために絵を描いてください:
ここに画像の説明を挿入
しかし、それについて話すのは非常に簡単です、理論と実践の間にはまだパフォーマンスの損失があります。

複数のデータコピーのプロセスでは、シングルスレッドのRedisは待機することしかできず、クライアントの要求に応答することはできません。現時点では、凝視することしかできず、パフォーマンスへの影響も大きくなっています。

かっこいい、どうすればいいの?心配しないでください、緩和戦略があります、そしてあなたは見下し続けるでしょう。

Redisには特別なものがあります パラメータ設定 メモリフラグメントを自動的にクリーンアップするために使用されます。

activedefrag yes

次のパラメータは、任意の条件を満たす後にクリーンアップできます。

active-defrag-ignore-bytes 100mb     :碎片达到100MB时,开启清理。

active-defrag-threshold-lower 10     :当碎片超过 10% 时,开启清理。

active-defrag-threshold-upper 100    :内存碎片超过 100%,尽最大清理。

処理の過程で、パフォーマンスを確保しながら、通常のリクエストへの影響を回避するため。Redisは、CPU使用率を監視するためのパラメーターも提供します。次の条件が満たされた場合にのみ、クリーンアップが正常に続行されます。

active-defrag-cycle-min 5  :清理内存碎片占用 CPU 时间的比例不低于此值,保证清理能正常开展。

active-defrag-cycle-max 75 :清理内存碎片占用 CPU 时间的比例不高于此值。一旦超过则停止清理,从而避免在清理时,大量的内存拷贝阻塞 Redis,导致其它请求延迟。

おすすめ

転載: blog.csdn.net/QiuHaoqian/article/details/110925393