redisに関するいくつかの小さなこと(4)redisの期限切れポリシーとメモリ淘汰メカニズム

2564 ワード

テキストリンク:https://juejin.im/post/5ce64da451882532e24cf464
1.データが期限切れになった理由
まず、redisはデータキャッシュに用いられるものであり、データストレージに用いられるものではない(もちろんデータベースに用いてもよい)ため、データが期限切れになったり、期限切れになったりするデータがなくなったりすることを理解しなければならない.②redisのデータはメモリに格納されているが、メモリは限られており、多くのデータを見逃すことは不可能である.例えば10 Gのメモリしかなく、20 Gのデータを中に入れたい場合、10 Gのデータが失われることになる.
2.redisの期限切れポリシーはどのようなものですか?
redisは、「定期削除+不活性削除」の期限切れポリシーを採用しています.①定期削除原理:定期削除とは、redisが100 ms毎に無作為に有効期限を設定したキーを抽出し、有効期限が切れたかどうかを検出し、有効期限が切れたら削除することを意味する.なぜすべてではなく一部を選択するのか:これがredisの中に大量のkeyが期限切れを設定している場合、すべてを検出するとCPU負荷が高くなり、検出に多くの時間を浪費し、redisを直接切ることになるからです.すべては一部のみ抽出され、すべて検査されません.問題が発生します:このようにすると大量の期限切れのkeyが削除されていません.これは、大量のkeyが期限切れになったのに、redisのメモリが大量に消費されている場合がある理由です.この問題を解決するために、このポリシーを不活性に削除する必要があります.
②惰性削除原理:惰性削除はredisが自発的に削除するのではなく、あるkeyを取得するときに、redisはまずこのkeyが期限切れであるかどうかを検出し、期限切れでない場合は返し、期限切れであれば、redisはこのkeyを削除し、返しません.このような2つの戦略は、期限切れのkeyが最終的に必ず削除されることを保証していますが、これは最終的に必ず削除されることを保証しています.もし定期的に期限切れのkeyを大量に削除し、私たちもタイムリーにこれらのkeyにアクセスしていなければ、これらのkeyは削除されませんか?私たちのメモリをずっと占めているのではないでしょうか.これでredisメモリが消費されるのではないでしょうか.このような問題があるため、redisはメモリ淘汰メカニズムを導入して解決した.
3.メモリ淘汰メカニズム
メモリ淘汰メカニズムは、redisのメモリが多すぎる場合、メモリ淘汰を行うことを保証します.つまり、keyの一部を削除し、redisのメモリ占有率が高すぎないことを保証します.では、keyは削除されますか?redisは6つのメモリ淘汰ポリシーを提供し、私たちは選択することができます.6つのポリシーは以下の通りです:1 noeviction:メモリが新しい書き込みデータを収容するのに不足している場合、新しい書き込み操作はエラーを報告し、新しいデータを書き込むことができません.一般的には採用されません.②allkeys-lru:新しい書き込みデータを格納するメモリが不足している場合、キースペースで最近最も使用されているkeyを削除するのが最も一般的です.③allkeys-random:新しく書き込まれたデータを格納するためにメモリが不足している場合、キー空間ではkeyをランダムに削除し、一般的には使用しません.④volatile-lru:volatile-lru:新しい書き込みデータを格納するためにメモリが不足している場合は、有効期限が設定されているキースペースから、最近最も使用されているkeyを削除します(これは一般的には適切ではありません).⑤volatile-random:新しい書き込みデータを格納するメモリが不足している場合、有効期限が設定されているキースペースからキーをランダムに削除します.⑥volatile-ttl:新しい書き込みデータを格納するためにメモリが不足している場合、有効期限が設定されているキースペースに、より早い有効期限が設定されているキーを優先的に削除します.
4.LRUアルゴリズムを手書きで書く
//  JavaLinkedHashMap  
public class LRUCache extends LinkedHashMap{
      private final int CACHE_SIZE;
      
      //            
      public LRUCache(int cacheSize){
           //  hashmap     ,      true    linkedhashmap           ,
           //        ,        
           super((int)Math.ceil(cacheSize/0.75)+1,0.75f,true);
           CACHE_SIZE = CacheSize;
      }

      @Override
      protected boolean removeEldestEntry(Map.Entry eldest){
           // map                 ,          。
           return size() > CACHE_SIZE;
      }
}