Java面接突破(22)-Redis期限切れポリシーおよび手書きLRU

4293 ワード

0 Githubへようこそ
乾物だらけの技術公衆番号へようこそ
1面接問題
Redisの期限切れポリシーにはどのようなものがありますか?メモリの淘汰メカニズムはどれらがありますか?LRUコードを手書きで実装しますか?
2ポイント分析
1)redisに書いたデータはどうしてなくなったのですか.
生産環境のredisはどうしてよくデータを失うのですか?書き込みましたが、しばらくすると無くなるかもしれません.
この質問はredisが役に立たないことを意味しますよね.redisはキャッシュですが、保存したのではないでしょうか.
キャッシュとは?メモリをキャッシュにする.メモリは無限ですか.メモリは貴重で限られていますが、ディスクは安価で大量です.1台の機械で数十Gのメモリがあるかもしれませんが、Tのハードディスク容量はいくつかあります.redisは主にメモリに基づいて高性能、高同時読み書き操作を行う.
メモリが限られている以上、例えばredisは10個のGしか使えません.もし中に20個のGのデータを書いたら、どうしますか.もちろん10個のGのデータを乾かして、10個のGのデータを残します.では、どのようなデータを殺しますか?どのデータを保持しますか?もちろん、あまり使われていないデータを乾かして、よく使われているデータを残します.
だから、これはキャッシュの最も基本的な概念で、データは期限切れになります.自分で期限切れを設定するか、redisが自分でやります.
set key value     (1  )

setが入ったkeyは、1時間後に無くなってしまい、失効してしまいました
2)データが期限切れになったのに、どうしてメモリを使っているのですか.
もう1つは、期限切れを設定したら、redisがどのように期限切れになったか知っていますか?いつ削除しますか?もしあなたが知らないならば、前にある人は聞いて、どうして多くのデータは明らかに期限切れになるべきで、結果はredisメモリの占有量がまだ高いことを発見しますか?それはredisがどのように期限切れのkeyを削除したのか分からないからです.
redisメモリは全部で10 gで、あなたは今中に5 gのデータを書いて、結果はこれらのデータは明らかにあなたがすべて期限切れの時間を設定したのに、これらのデータは1時間後にすべて期限切れになることを要求して、結果は1時間後に、あなたは帰って見て、redis機械、どのようにメモリが50%を占めますか?5 gのデータが期限切れになったので、redisから調べましたが、調べられませんでした.結局、期限切れのデータはredisのメモリを消費していました.
もしあなたがこの問題さえ知らないならば、上がってくるとぼんやりしていて、答えられなくて、その線上であなたがコードを書く時、当然redisに書くデータはきっと存在すると思って、後でシステムの各種の抜け穴とバグを招いて、誰が責任を負いますか?
3詳細
3.1有効期限の設定
私たちがセットキーを置くとき、expire timeをあげることができます.期限切れです.このキーを指定します.例えば、1時間しか生きられませんか.10分?これは役に立ちます.キャッシュが期限切れになると失効することを自分で指定できます.
もしあなたが1つのkeyを設定して1時間しか生きられないとしたら、次の1時間後、redisはどのようにしてこのkeyを削除しますか?
定期削除+不活性削除
定期的に削除
redisのデフォルトは、100 msおきに期限切れが設定されているkeyをランダムに抽出し、期限切れかどうかを確認し、期限切れであれば削除することです.
仮にredisに10万個のkeyが入っていて、期限切れが設定されているとしたら、数百ミリ秒おきに10万個のkeyをチェックすると、redisは基本的に死んでしまい、cpu負荷が高くなり、検査の期限切れkeyに消費されます.
ここでは、100 msごとにすべての設定の期限切れのkeyを巡るのではなく、パフォーマンス上の災害です.実際にredisは100 msおきにいくつかのkeyをランダムに抽出して検査し削除した.
しかし問題は、定期的に削除すると、多くの期限切れkeyが時間になっても削除されない可能性がありますが、どうすればいいのでしょうか.だから
不活性削除
つまり、あるキーを取得したとき、redisはチェックします.このキーが期限切れに設定されている場合、期限切れになっていますか?期限が切れたら削除され、何も返されません.
キーが時間になると削除されるのではなく、あなたがこのキーを調べたとき、redisは怠け者にチェックします.
上記の2つの手段を組み合わせることで、期限切れのkeyが必ず乾くことを保証します.
簡単です.つまり、あなたの期限切れkeyは、定期的に削除されていないので、メモリに残っていて、メモリを占有しています.あなたのシステムがそのkeyを調べない限り、redisに削除されません.
しかし、実際には問題があります.定期的に削除すると期限切れのkeyがたくさん漏れて、それからあなたもタイムリーに調べていません.惰性で削除していません.この時どうなりますか.大量の期限切れのkeyがメモリの中で積み上げて、redisメモリのブロックが消耗して、どのように整えますか?
答えは、メモリ淘汰メカニズムです.
3.2メモリの廃棄
redisのメモリが多すぎる場合、メモリの淘汰が行われます.次のポリシーがあります.
redisは10個のkeyで、今はもういっぱいで、redisは5個のkeyを削除する必要があります
1 key、最近1分で100回1 key、最近10分で50回1 key、最近1時間倍で1回
  • noeviction:メモリが不足して新しい書き込みデータを格納すると、新しい書き込み操作がエラーになります.これは一般的に誰も使っていないでしょう.(気持ち悪いですが、デフォルト)
  • allkeys-lru:新しい書き込みデータを格納するためにメモリが不足する場合、キー空間で最近最も使用されているkey(最も一般的な)
  • を除去する.
  • allkeys-random:新しい書き込みデータを格納するメモリが不足している場合、キー空間でランダムにキーを削除します.これは一般的に誰も使っていません.なぜランダムにするのか、最近最も少ないキーを
  • 乾かすに違いありません.
  • volatile-lru:新しい書き込みデータを格納するためにメモリが不足している場合、有効期限が設定されたキースペースから、最近最も使用されているkey(不適切)
  • を除去する.
  • volatile-random:新しい書き込みデータを格納するためにメモリが不足する場合、有効期限が設定されたキースペースからkey
  • をランダムに削除します.
  • volatile-ttl:新しい書き込みデータを格納するメモリが不足する場合、有効期限が設定されたキースペースにおいて、より早い有効期限があるkeyが
  • を優先的に削除する.
    3.3 LRUを手書きで書く
    确かに时にはこれを闻くことがあります.もし一部の候补者が确かに5関を过ぎて6将を斩って、前の问题はすべてよく答えて、それでは実は彼にLRUアルゴリズムを书いて、コードの基础を考察することができます
    あなたは現場で最も原始的なLRUアルゴリズムを手書きすることができて、そのコードの量は大きすぎて、あまり現実的ではありません
    public class LRUCache extends LinkedHashMap {
        
    private final int CACHE_SIZE;
    
        //                  
        public LRUCache(int cacheSize) {
            super((int) Math.ceil(cacheSize / 0.75) + 1, 0.75f, true); //         hashmap     ,      true    linkedhashmap           ,        ,        
            CACHE_SIZE = cacheSize;
        }
    
        @Override
        protected boolean removeEldestEntry(Map.Entry eldest) {
            return size() > CACHE_SIZE; //         map                 ,          
        }
    
    }

    少なくともあなたも上のコードを書かなければなりません.自分の純粋な手作業で下から自分のLRUを作ることを求めませんが、少なくとも既存のjdkデータ構造を利用してjava版のLRUを実現する方法を知っています.
    リファレンス
    『Javaエンジニア面接突撃第1期-中華石杉先生』
    本文はブログの1文の多発プラットフォームから
    OpenWriteリリース!