Redis的过期策略能介绍一下嘛,能不能手写一个LRU算法
Redis中的数据失效方式
设置TTL(过期时间)
RedisTTL时间到了之后,Redis如何批量删除key以及Value
定期删除+惰性删除
定期删除:指的是Redis默认每隔100MS就随机抽取一些设置了过期时间的key,检查其是否过期,如果过期了,就直接删除,注意,这个地方redis并不是每隔100ms就遍历所有的设置过期时间的key,而是抽取一部分key来检查和删除
但问题就是定期删除可能会导致很多过期key到了过期时间并没有被删除掉,所以需要惰性删除,就是说,当命中某个key的时候,Redis会检查一下这个Key如果设置了过期时间,那么这个key是否已经删除,如果过期了后,此时就会被删除
但是这样还有一个问题,如果一个key不仅逃离了定期删除而且还长时间key没有命中,长期积累下来的话会导致Redis内存耗尽,如何处理
走内存淘汰策略
内存淘汰
如果Redis的内存占用过多的时候,此时会进行内存淘汰,有如下一些策略:
- noevication:当内存不足以容纳新写入的数据时,新写入操作会报错,这个一般没人用,太恶心了
- allkeys-lru:当内存不足以容纳新写入的数据时,移除最近最少使用的key(这个是最常用的)
- allkeys-random:当内存不足以容纳新写入的数据的时候,在键空间中随机移除某个key,这个也没人用,随机移除简直要了命了
- valatile-lru: 当内存不足以容纳新写入的数据时,在设置了过期时间的键空间中,移除最少使用的key
- valtile-random:当内存不足以容纳新写入的数据的时候,在设置了过期时间的键空间中,随即移除某个key
- volatile-ttl:当内存不足一容纳写入新数据是,在设置了过期时间的键空间中,有更早过期时间的key优先移除
如何手写一个LRU算法
public class LRUCache<K,V> extends LinkedHashMap<K,V> {
private final int CACHE_SIZE;
//这里就是传递进来最多能缓存多少数据
pubilc LRUCache(int cacheSize){
super(Math.ceil(cacheSize/0.75) + 1, 0.75f, true);//这块就是设置一个hashMap的初始化大小,同时最后一个true指的是让likedhashMap按照访问顺序来进行排序,最近访问的放在头,最老访问的放在尾
CACHE_SIZE=cacheSize;
}
protected boolean removeEldestEntry(Map.Entry eldest){
return size() > CACHE_SIZE;//这个意思就是当Map中的数据量大于指定的缓存个数的时候,自动删除最好的数据
}
}