LRU (redis 的LRU 加自己实现的linkedHashMap)

本文很有用

一、概念:
什么是LRU算法? LRU是Least Recently Used的缩写,即最近最久未使用(其实就是从当前看最长时间没用到的),常用于页面置换算法,是为虚拟页式存储管理服务的。

二、代码:
重写 linkedHashMap 实现了 lru
package com.heyjl.linkedhashmap_lru;

/**
 * http://blog.csdn.net/yangpl_tale/article/details/44998365
 * http://flychao88.iteye.com/blog/1977653
 *
 * LRU是一种淘汰策略,就是内存达到容量后,最近未使用的就扔掉,
 * linkedHashMap 正常是不限量的不删除元素,
 * 但是如果继承linkedHashMap,设置他的容量就可以LRU
 * Created by jalo on 2017/11/9.
 */
import java.util.*;

//扩展一下LinkedHashMap这个类,让他实现LRU算法
class LRULinkedHashMap extends LinkedHashMap{
    //定义缓存的容量
    private int capacity;
    private static final long serialVersionUID = 1L;
    //带参数的构造器
    LRULinkedHashMap(int capacity){
        //调用LinkedHashMap的构造器,传入以下参数
        super(16,0.75f,true);
        //传入指定的缓存最大容量
        this.capacity=capacity;
    }
    //实现LRU的关键方法,如果map里面的元素个数大于了缓存最大容量,则删除链表的顶端元素
    @Override
    public boolean removeEldestEntry(Map.Entry eldest){
        System.out.println(eldest.getKey() + "=" + eldest.getValue());
        return size()>capacity;
    }
}
//测试类
class LRU{
    public static void main(String[] args) throws Exception{

        //指定缓存最大容量为4
        Map map=new LRULinkedHashMap(4);
        map.put(9,3);
        map.put(7,4);
        map.put(5,9);
        map.put(3,4);
        map.put(6,6);
        //总共put了5个元素,超过了指定的缓存最大容量
        //遍历结果
        for(Iterator> it=map.entrySet().iterator();it.hasNext();){
            System.out.println(it.next().getKey());
        }
    }
}

三、redis 的置换策略:
当Redis内存使用达到maxmemory时,需要选择设置好的maxmemory-policy进行对老数据的置换。 
下面是可以选择的置换策略:
  • noeviction: 不进行置换,表示即使内存达到上限也不进行置换,所有能引起内存增加的命令都会返回error
  • allkeys-lru: 优先删除掉最近最不经常使用的key,用以保存新数据
  • volatile-lru: 只从设置失效(expire set)的key中选择最近最不经常使用的key进行删除,用以保存新数据
  • allkeys-random: 随机从all-keys中选择一些key进行删除,用以保存新数据
  • volatile-random: 只从设置失效(expire set)的key中,选择一些key进行删除,用以保存新数据
  • volatile-ttl: 只从设置失效(expire set)的key中,选出存活时间(TTL)最短的key进行删除,用以保存新数据
选择合适的置换策略是很重要的,这主要取决于你的应用的访问模式,当然你也可以动态的修改置换策略,并通过用Redis命令——INFO去输出cache的命中率情况,进而可以对置换策略进行调优
一般来说,有这样一些常用的经验:
  • 在所有的key都是最近最经常使用,那么就需要选择allkeys-lru进行置换最近最不经常使用的key,如果你不确定使用哪种策略,那么推荐使用allkeys-lru
  • 如果所有的key的访问概率都是差不多的,那么可以选用allkeys-random策略去置换数据
  • 如果对数据有足够的了解,能够为key指定hint(通过expire/ttl指定),那么可以选择volatile-ttl进行置换
参考: http://blog.csdn.net/cjfeii/article/details/47259519

你可能感兴趣的:(LRU (redis 的LRU 加自己实现的linkedHashMap))