【Redis】Redis的過時策略

redis過時策略

在使用redis作緩存的時候,咱們經常會設置過時時間。那麼redis是如何清理這些過時的數據呢?java

答案是: 按期刪除 + 惰性刪除redis

  • 按期刪除: redis每100ms就會隨機抽查刪除過時的數據。可是這種方法有時候會留下大量過時但沒有被抽查到的過時數據,白白浪費內存。
  • 惰性刪除: 惰性刪除此時就派上用場了,當用戶獲取數據時,redis會先檢查該數據有沒有過時,若是過時就刪除。

聽上去按期刪除+惰性刪除好像很完美的樣子,but過時的數據用戶又沒有及時訪問,那麼內存中仍是會存在大量的過時數據。此時應該採用redis內存淘汰機制。算法

redis內存淘汰機制

  • noeviction:內存不足以寫入新數據的時候會直接報錯。
  • allKeys-lru:內存不足以寫入新數據時候,移除最近最少使用的key。
  • allKeys-random: 內存不足以寫入新數據時,隨機移除key。
  • volatile-lru: 內存不足以寫入新數據時,在設置了過時時間的key當中移除最近最少使用的key。
  • volatile-random: 內存不足以寫入新數據時,在設置了過時時間的key中,隨即移除key。
  • volatile-ttl: 內存不足以寫入新數據時,在設置了過時時間的key當中移除最早過時的key。

上面六種你能夠這麼記:緩存

  • 不移除直接報錯: noeviction。
  • 在全部key中移除: 1.allKeys-lru 2. allKeys-random
  • 在設置了過時時間的key中移除: 1. volatile-lru 2. volatile-random 3.volatile-ttl

通常經常使用allKeys-lrudom

實現一個簡單的lru(最近最少使用算法)

package com.amber;

import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;

public class LRULinkedHashMap<K, V> extends LinkedHashMap<K, V> {
    //最大容量
    private final int maxCapacity ;
    // 默認增加因子
    private static final float DEFAULT_LOAD_FACTOR = 0.75f;

    public LRULinkedHashMap(int maxCapacity) {
        super(maxCapacity, DEFAULT_LOAD_FACTOR, true);
        this.maxCapacity = maxCapacity;
    }
    
    @Override
    protected boolean removeEldestEntry(Map.Entry<K, V> entry) {
        if(size()>maxCapacity)
            return true;
        else
            return false;
    }

    public static void main(String[] args) {
        LRULinkedHashMap<String, String> lruLinkedHashMap = new LRULinkedHashMap(5);
        lruLinkedHashMap.put("1", "1");
        lruLinkedHashMap.put("2", "2");
        lruLinkedHashMap.put("3", "3");
        lruLinkedHashMap.put("4", "4");
        lruLinkedHashMap.put("5", "5");
        Iterator<Map.Entry<String, String>> iterator = lruLinkedHashMap.entrySet().iterator();
        while (iterator.hasNext()) {
            System.out.println(iterator.next());
        }
        lruLinkedHashMap.get("1");
        System.out.println("超出最大容量");
        lruLinkedHashMap.put("6", "6");
        iterator = lruLinkedHashMap.entrySet().iterator();
        while (iterator.hasNext()) {
            System.out.println(iterator.next());
        }

    }
}

結果ide

1=1
2=2
3=3
4=4
5=5
超出最大容量
3=3
4=4
5=5
1=1
6=6

Process finished with exit code 0

根據上述結果能夠看到,當超出最大容量時移除的是第二個結點,而不是第一個結點,所以一個簡單的lru算法就實現了this

super(maxCapacity, DEFAULT_LOAD_FACTOR, true);

調用的是父類的code

public LinkedHashMap(int var1, float var2, boolean var3) {
        super(var1, var2);
        this.accessOrder = var3;
    }

accessOrder爲true表示會把最新訪問的數據放到最後一個節點,默認falseblog

相關文章
相關標籤/搜索