Redis内存回收

一、Redis内存回收策略

回收策略 描述
noeviction 当到达内存限制时返回错误。当客户端尝试执行命令时会导致更多内存占用(大多数写命令,除了 DEL 和一些例外)
allkeys-lru 回收最近最少使用(LRU)的键,为新数据腾出空间
volatile-lru 回收最近最少使用(LRU)的键,但是只回收有设置过期的键,为新数据腾出空间
allkeys-random 回收随机的键,为新数据腾出空间
volatile-random 回收随机的键,但是只回收有设置过期的键,为新数据腾出空间
volatile-ttl 回收有设置过期的键,尝试先回收离 TTL 最短时间的键,为新数据腾出空间


二、LRU原理

      LRU(Least recently used,最近最少使用),选择最近一段时间内,最久未使用的对象将其淘汰。

Redis内存回收_第1张图片

三、LRU经典实现算法 

1. 新数据插入到链表头部;

2. 每当缓存命中(即缓存数据被访问),则将数据移到链表头部;

3. 当链表满的时候,将链表尾部的数据丢弃。

四、JDK中LinkedHashMap实现LRU(HashMap+双向链表)

       LinkedHashMap的实现原理和HashMap并没有本质区别,下图中除去红色的虚连接线,其结构就是典型的HashMap.

和HashMap的不同的是,其Entry节点中,增加了两个指针:befor和after,用来维护双向链表结构.

带有accessOrder的构造函数,accessOrder为false,按照插入的顺序进行排序,accessOrder为true,按照访问的顺序进行排序

public LinkedHashMap(int initialCapacity,float loadFactor,boolean accessOrder) {

super(initialCapacity, loadFactor);
this.accessOrder = accessOrder;

}

利用LinkedHashMap实现LRU的简单例子:

 

class LRUCache extends LinkedHashMap{

private int capacity;
private static final long serialVersionUID = 1L;

 

LRUCache(int capacity){
super(16,0.75f,true);
this.capacity=capacity;
}

@Override
public boolean removeEldestEntry(Map.Entry eldest){ 
return size()>capacity;
}

}

五、Redis 实现的LRU算法

       Redis 的 LRU 算法不是一个精确的实现,是近似的 LRU 算法。通过采样一小部分键,然后在采样键中回收最适合(拥有最久访问时间)的那个。

       采样的个数可以通过如下配置文件修改:

          maxmemory-samples 5

       1)redis的内存回收如下图所示:

你可能感兴趣的:(Redis)