您的位置:首页 > 数据库 > Redis

【面试】Redis的过期淘汰策略介绍一下?手写一下LRU?

2020-03-08 14:33 761 查看

发现很多铁子还是不够了解Redis的过期淘汰策略

  • 之前有个铁子问我,说我的redis怎么经常会丢掉一些数据,写进去了,过一会可能就没了?
  • 还有个铁子说,我的key明明都过期了,怎么还占用着内存啊?

假设我设置了一批key的过期时间为1小时,1小时后redis是怎么对这批key进行删除的?

答案是:定期删除+惰性删除
所谓定期删除,指的是redis默认是每隔100ms就随机抽取一些设置了过期时间的key,检查其是否过期,如果过期就删除。注意,这里可不是每隔100ms就遍历所有设置了过期时间的key而是随机检查删除。

那有些key没有被随机到没被删掉咋整?
所以就有了惰性删除。这就是说,在你获取某个key的时候,并且这个key设置了过期时间,redis会先检查一下该key是否过期,如果过期了此时会进行删除并且不给你返回任何东西。没过期的话就该怎样怎样。

所以说,redis是采用了定期删除+惰性删除的策略,并不是设置了过期时间的key一到时间就一定会被删除。他会先随机抽取进行删除,没被随机到的停留在内存中,除非你去查一下那个key,才会被redis给删除。

那如果定期删除漏掉了很多key,而且你也没有去查询走惰性删除,还是会有大量过期的key堆积在你的内存中可咋办?。

答案:走内存淘汰机制
内存淘汰机制的意思就是:如果redis的内存占用过多的时候,为了保证新数据的成功写入,会进行数据淘汰。

有如下内存淘汰机制:

  • noeviction:当内存不足以容纳新写入的数据时,写入操作会报错。
  • allkeys-lru:优先删除最近最少使用的key,所有的key通用。(常用)
  • allkeys-random:所有的key通过,随即删除部分key。
  • volatile-lru:只限于设置了过期时间的key,并且优先删除最近最少使用的key。
  • volatile-random:只限于设置了过期时间的key,随机删除部分key。
  • volatile-ttl:只限于设置了过期时间的key,优先删除剩余时间最短的key。

到这我想这两位铁子应该知道问题所在了。

手撕LRU

根据我的观察,当你说到allkeys-lru这个内存淘汰机制之后,有很多面试官会让你手写一下LRU算法,考察一下你的编码功底。

虽然心里MMP,但是脸上还得笑嘻嘻。
但你可别搞原始的那个,那真TM多,写不完的。下面演示一个折中一点的。

public class LRUCache<K,V> extends LinkedHashMap<K,V> {

private final int CACHE_SIZE;

/**
* 这里就是传递进来最多能缓存多少数据
* @param cacheSize 缓存大小
*/
public LRUCache(int cacheSize){
//这块就是设置一个hashmao的初始大小,同时最后一个true指的是让linkedHashMap按照访问顺序来进行排序
//最近访问的放在头,最老访问的放在尾。
super((int)Math.ceil(cacheSize / 0.75) + 1 , 0.75f , true);
CACHE_SIZE = cacheSize;
}

@Override
protected boolean removeEldestEntry(Map.Entry eldest){
//这个意思就是说当map中的数据量大于指定的缓存个数的时候就自动删除最老的数据
return size() > CACHE_SIZE;
}
}
  • 点赞
  • 收藏
  • 分享
  • 文章举报
一阳Eayon 发布了8 篇原创文章 · 获赞 2 · 访问量 281 私信 关注
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: