手寫Redis之LRU淘汰算法

一、內存淘汰機制

redis 內存淘汰機制有以下幾個:

noeviction: 當內存不足以容納新寫入數據時,新寫入操作會報錯,這個一般沒人用吧,實在是太噁心了。
allkeys-lru:當內存不足以容納新寫入數據時,在鍵空間中,移除最近最少使用的 key(這個是最常用的)。
allkeys-random:當內存不足以容納新寫入數據時,在鍵空間中,隨機移除某個 key,這個一般沒人用吧,爲啥要隨機,肯定是把最近最少使用的 key 給幹掉啊。
volatile-lru:當內存不足以容納新寫入數據時,在設置了過期時間的鍵空間中,移除最近最少使用的 key(這個一般不太合適)。
volatile-random:當內存不足以容納新寫入數據時,在設置了過期時間的鍵空間中,隨機移除某個 key。
volatile-ttl:當內存不足以容納新寫入數據時,在設置了過期時間的鍵空間中,有更早過期時間的 key 優先移除。

LRU算法實現類:

package com.test.day01;

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

/**
 *  手寫LRU 算法
 * @author zc
 *
 */
public class LRUCache<K,V> extends LinkedHashMap<K,V>{
    
	
	private static final long serialVersionUID = 1L;
	
	//設置緩存的大小
	private int CACHE_SIZE;
	
	/**
	 *  構造函數初始化緩存的大小
	 * @param cacheSize  緩存大小
	 */
	public LRUCache(int cacheSize) {
		
		// true 表示讓linkedHashMap 按照訪問順序來進行排序,最近訪問的放在頭部,最老訪問的放在尾部
		super((int)Math.ceil(cacheSize/0.75)+1,0.75f,true);
		
		this.CACHE_SIZE =cacheSize;
	}
	
	
	/***
	 *    緩存是否已滿
	 */
	@Override
	protected boolean removeEldestEntry(Map.Entry<K, V>eldest) {
		
		//當map中的數據量大於指定的緩存個數的時候,就自動刪除最老的數據
		boolean bool= size()> CACHE_SIZE;
		if(bool) {
			System.out.println("清除緩存key:"+eldest.getKey());
		}
		
		return bool;
	}
	
	
	public static void main(String[] args) {
		
		LRUCache<String,String> cache =new LRUCache<String,String>(5);
		cache.put("1", "1");
		cache.put("2", "2");
		cache.put("3", "3");
		cache.put("4", "4");
		cache.put("5", "5");
		System.out.println("初始化: ");
		System.out.println(cache.keySet());
		System.out.println("訪問3: ");
		cache.get("3");
		System.out.println(cache.keySet());
		System.out.println("訪問2: ");
		cache.get("2");
		System.out.println(cache.keySet());
		System.out.println("增加數據 6,7: ");
		cache.put("6","6");
		cache.put("7","7");
		System.out.println(cache.keySet());
		
	
	}
}

輸出:

初始化: 
[1, 2, 3, 4, 5]
訪問3: 
[1, 2, 4, 5, 3]
訪問2: 
[1, 4, 5, 3, 2]
增加數據 6,7: 
清除緩存key:1
清除緩存key:4
[5, 3, 2, 6, 7]
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章