缓存三连击——聊聊Redis过期策略?内存淘汰机制?再手写一个LRU 吧!

Posted 码农突围

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了缓存三连击——聊聊Redis过期策略?内存淘汰机制?再手写一个LRU 吧!相关的知识,希望对你有一定的参考价值。

点击上方“ 码农突围 ”,马上关注
这里是码农充电第一站,回复“666”,获取一份专属大礼包
真爱,请设置“星标”或点个“在看”
来自:石杉的架构笔记
作者:魏武归心


大家好,今天我和大家想聊一聊有关redis的过期策略的话题。


听到这里你也许会觉得:“我去,我只是个日常搬砖的,这种偏底层的知识点,我需要care吗?”


话虽如此·,但是兄die,如果你连标题上问题都不知道,上来就懵了,回答不出来,那面试官就有可能有这样的担心:


“这小伙子对这些问题一无所知,会不会想当然的认为写进 redis 的数据就一定会存在,后面导致系统各种 bug,谁来负责呢?


说到这,你还会觉得这样的问题毫无意义吗?


在开始正题之前,我想问大家这样的两个问题:


1. 往 redis 写入的数据怎么没了?

可能有同学会遇到,在生产环境的 redis 经常会丢掉一些数据,写进去了,过一会儿可能就没了。


我的天,同学,你问这个问题就说明 redis 你就没用对啊。redis 是缓存,你给当存储了是吧?


啥叫缓存?


用内存当缓存。内存是无限的吗,内存是很宝贵而且是有限的,磁盘是廉价而且是大量的。


可能一台机器就几十个 G 的内存,但是可以有几个 T 的硬盘空间。redis 主要是基于内存来进行高性能、高并发的读写操作的。


那既然内存是有限的,比如 redis 就只能用 10G,你要是往里面写了 20G 的数据,会咋办?


当然会干掉 10G 的数据,然后就保留 10G 的数据了。


那干掉哪些数据?保留哪些数据?当然是干掉不常用的数据,保留常用的数据了。


2. 数据明明过期了,怎么还占用着内存?

这是由 redis 的过期策略来决定。


有了以上的铺垫,我们闲言少叙正题现在开始:


redis 过期策略

redis 过期策略是:定期删除+惰性删除。


所谓定期删除,指的是 redis 默认是每隔 100ms 就随机抽取一些设置了过期时间的 key,检查其是否过期,如果过期就删除。


假设 redis 里放了 10w 个 key,都设置了过期时间,你每隔几百毫秒,就检查 10w 个 key,那 redis 基本上就死了,cpu 负载会很高的,消耗在你的检查过期 key 上了。


注意,这里可不是每隔 100ms 就遍历所有的设置过期时间的 key,那样就是一场性能上的灾难。


实际上 redis 是每隔 100ms 随机抽取一些 key 来检查和删除的。


但是问题是,定期删除可能会导致很多过期 key 到了时间并没有被删除掉,那咋整呢?


所以就是惰性删除了。这就是说,在你获取某个 key 的时候,redis 会检查一下 ,这个 key 如果设置了过期时间那么是否过期了?如果过期了此时就会删除,不会给你返回任何东西。


获取 key 的时候,如果此时 key 已经过期,就删除,不会返回任何东西。


但是实际上这还是有问题的,如果定期删除漏掉了很多过期 key,然后你也没及时去查,也就没走惰性删除,此时会怎么样?


如果大量过期 key 堆积在内存里,导致 redis 内存块耗尽了,咋整?


答案是:走内存淘汰机制。


内存淘汰机制

redis 内存淘汰机制有以下几个:


  • noeviction: 当内存不足以容纳新写入数据时,新写入操作会报错,这个一般没人用吧,实在是太恶心了

  • allkeys-lru:当内存不足以容纳新写入数据时,在键空间中,移除最近最少使用的 key(这个是最常用的)

  • allkeys-random:当内存不足以容纳新写入数据时,在键空间中,随机移除某个 key,这个一般没人用吧,为啥要随机,肯定是把最近最少使用的 key 给干掉啊。

  • volatile-lru:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,移除最近最少使用的 key(这个一般不太合适)

  • volatile-random:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,随机移除某个 key

  • volatile-ttl:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,有更早过期时间的 key 优先移除



手写一个 LRU 算法

你可以现场手写最原始的 LRU 算法,那个代码量太大了,似乎不太现实。


不求自己纯手工从底层开始打造出自己的 LRU,但是起码要知道如何利用已有的 JDK 数据结构实现一个 Java 版的 LRU。


缓存三连击——聊聊Redis过期策略?内存淘汰机制?再手写一个LRU 吧!

---END---
重磅!码农突围-技术交流群已成立

扫码可添加码农突围助手,可申请加入码农突围大群和细分方向群,细分方向已涵盖: Java、Python、机器学习、大数据、人工智能 等群。
一定要备注: 开发方向+地点+学校/公司+昵称(如Java开发+上海+拼夕夕+猴子) ,根据格式备注,可更快被通过且邀请进群

缓存三连击——聊聊Redis过期策略?内存淘汰机制?再手写一个LRU 吧!
▲长按加群
顺说句题外话,有不少人想加鱼哥微信,鱼哥姑且放出来,但是坑位有限哦
缓存三连击——聊聊Redis过期策略?内存淘汰机制?再手写一个LRU 吧!
缓存三连击——聊聊Redis过期策略?内存淘汰机制?再手写一个LRU 吧!
有热门推荐

以上是关于缓存三连击——聊聊Redis过期策略?内存淘汰机制?再手写一个LRU 吧!的主要内容,如果未能解决你的问题,请参考以下文章

聊聊 Redis 内存淘汰策略

缓存过期策略+Redis内存淘汰机制

Redis缓存过期处理与内存淘汰机制

Redis 缓存过期处理与内存淘汰机制

Redis内存淘汰机制

Redis的过期策略和内存淘汰机制