blog

redisのメモリ消去ポリシー

allkeys-lruは8分の2ルールのシナリオ、すなわち、20%の鍵が80%の確率で アクセスされ、80%の鍵が20%の確率でアクセスされるような場合に適用されます。正式名称:べき乗則 volati...

Apr 8, 2020 · 4 min. read
シェア

段階的廃止戦略の発動時期

  • クライアントが新しいコマンドを実行すると、メモリにデータが追加されます。
  • redisはメモリ使用量をチェックし、それがmaxmemoryを超えた場合、ポリシーに従ってキーが削除されます。
  • 次のコマンド、というように。

常にメモリ制限maxmemoryを超え、常にキーを削除してメモリ制限を下回る境界線 コマンドが多くのメモリを使用すると、メモリ制限maxmemoryを大幅に超えます。

maxmemoryは設定ファイルで設定するか、ランタイム・コマンドで設定します。64ビットのredisのデフォルトは無制限、32ビットのデフォルトは3GBです。

フェーズアウト戦略

  • noeviction : エラーを消去せずにそのまま返します。
  • allkeys-lru: すべてのキーのうち、最も最近使用されたキーを選択し、フェーズアウトします。
  • volatile-lru:有効期限があるキーのうち、最も最近使われたキーを選んで段階的に削除します。
  • allkeys-random: すべてのキーをランダムに選択して消去します。
  • volatile-random: 有効期限がある鍵の中から消去する鍵をランダムに選択します。
  • volatile-ttl:有効期限のある鍵を排除し、TTLが最も短い鍵を最初に排除。

volatileの消去戦略は、有効期限のある鍵を消去することであり、適格な鍵がない場合、 volatile-*の動作はnoevictionと同じです。

戦略の選び方

消去ポリシーはRedisの実行時に再設定できます。RedisのINFOコマンドを使ってキャッシュのヒット数とミス数を監視し、ポリシーを調整します。

  • allkeys-lruはtwo-eight principleのシナリオ、つまり20%の鍵が80%の確率でアクセスされ、80%の鍵が20%の確率でアクセスされるというようなシナリオに適用されます。正式名称:べき乗分布

  • allkeys-randomは、各キーにアクセスする確率がほぼ同じ場合に使用されます。

  • 異なるTTLを設定してRedisのノックアウトキーをブートストラップしたい場合は、volatile-ttlを使用できます。

volatile-lru および volatile-random ポリシーは、主に単一のインスタンスをキャッシュと永続キーのセットの両方に使用したい場合に便利です。しかし、通常はこのような問題を解決するために2つのRedisインスタンスを実行する方がよいでしょう。

有効期限の設定もメモリを消費するので、有効期限を設定せずに allkeys-lru ポリシーを使用するのが通常最も効率的です。

LRUの近似アルゴリズム

Redisは少数のキーをサンプリングすることでLRU近似アルゴリズムを実装しています。maxmemory-samples nは近似アルゴリズムの精度を調整します。nが大きいほどサンプルの数が多くなり、LRUの精度が向上し、アルゴリズムのパフォーマンスが低下し、排除対象のキーの選択がうまくなります。Redisはより多くのメモリを消費するため、本当のLRU実装を使用しません。Redisの近似は、べき乗分布が満たされるシナリオでは、真のLRU実装とほぼ同等です。

redisに一定量のデータを入れ、最初のキーから順番にアクセスすることで、最初のキーがLRU消去の最適な選択となり、さらに50%のデータを追加することで、半分のデータを強制的に消去します

左上:理論的な消去結果 右上:Redis 3.0近似のLRU 10サンプルの結果 理論値に非常に近い 左下:Redis 2.8近似のLRU 5サンプルの結果 右下:Redis 3.0近似のLRU 5サンプルの結果

  • ライトグレーはアウト。
  • グレーは廃止されず
  • 緑が新しく追加されたオブジェクト

RedisのLRUは古いデータのみを確率的に消去します。

データアクセスパターンがべき乗則に極めて類似している場合、LRU近似アルゴリズムは理論上のLRUとほぼ同等です。

キャッシュヒット率に影響があるかどうかを確認するために、サンプルを10に調整することはしばしば可能ですが、これはプロセスに余分なハードウェアリソースを追加します。

LFU

Redis 4.0以降、使用頻度が最も低く、アクセス頻度によって除外されます。

  • volatile-lfu
  • allkeys-lfu

LFUはLRUを近似したもので、各オブジェクトにアクセス頻度を表す数ビットのカウンタがあり、これも時間とともに徐々に小さくなります。

lfu-decay-time 1
lfu-log-factor 10

lfu-decay-time 1はカウンタが1分ごとに減衰することを意味し、0はスキャンされるたびに減衰することを意味します lfu-log-factorは、カウンタが訪問回数に応じてどの程度の速さで増加するかを決定します。

+--------+------------+------------+------------+------------+------------+
| factor | 100 hits | 1000 hits | 100K hits | 1M hits | 10M hits |
+--------+------------+------------+------------+------------+------------+
| 0 |  |  | 255 |
+--------+------------+------------+------------+------------+------------+
| 1 | 5 |  |
+--------+------------+------------+------------+------------+------------+
|  |  | 255 |
+--------+------------+------------+------------+------------+------------+
|  |  | 255 |
+--------+------------+------------+------------+------------+------------+
Read next

invalidateのソースコード解析を見る

Viewをカスタマイズする場合、Viewを更新するメソッドを使用するのが一般的ですが、この記事ではこれらのメソッドの実装を分析します。オーバーロードされたメソッドはいくつかありますが、最終的な実装は似ているので、まずは()から説明します。 別の...

Apr 8, 2020 · 13 min read