后端工程师的高阶面经
邓明
前 Shopee 高级工程师,Beego PMC
6888 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 50 讲
后端工程师的高阶面经
15
15
1.0x
00:00/00:00
登录|注册

31|缓存过期:为什么 Redis 不立刻删除已经过期的数据?

你好,我是大明。今天我们来讨论一个全新的话题——缓存。
缓存在实践中、面试中的重要性不言而喻。应该说,缓存用好了就能解决你大部分的性能问题。反过来,如果缓存没有用好,那么系统性能是不可能好的。
缓存在面试中也分成两个方向:一个是理论上缓存的设计,包括 Redis 的原理;一个是在实践中使用缓存的案例,聚焦在怎么使用缓存,怎么解决一致性问题。
那么今天我们先从第一个话题缓存的过期时间开始。

缓存命中率

缓存命中率是我们用来衡量缓存效果的关键指标。它的计算方式是缓存命中次数除以查询总次数。
在实践中,你要努力把缓存命中率提高到 90% 以上。不过,缓存命中率也受到业务模式的影响,有一些业务是没有办法做到 90% 以上的。
比如说有一些场景是缓存计算时间很长的结果,但是大部分请求都是小请求,也就是都不会命中缓存,这种时候缓存命中率可能连一半都没有。但是因为这些小请求计算很快,所以走实时计算响应时间也能接受,而且实时计算的数据更加准确。

实现过期机制的一般思路

从系统设计的角度来说,过期之类的机制可以考虑使用四种思路来实现。
定时删除:是指针对每一个需要被删除的对象启动一个计时器,到期之后直接删除。
延迟队列:也就是把对象放到一个延迟队列里面。当从队列里取出这个对象的时候,就说明它已经过期了,这时候就可以删除。
懒惰删除:是指每次要使用对象的时候,检查一下这个对象是不是已经过期了。如果已经过期了,那么直接删除。
定期删除:是指每隔一段时间就遍历对象,找到已经过期的对象删除掉。
针对这四种思路的优缺点,你可以参考下面的表格。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

本文深入探讨了Redis缓存过期机制的实现思路和优化方法。重点讨论了缓存命中率与过期时间的关系,以及优化过期时间的两个方向。此外,还介绍了Redis的过期key的删除策略,包括懒惰删除和定期删除,并强调了定期删除和懒惰删除策略的优势。文章还讨论了控制定期删除的频率以及从库处理过期key的情况。最后,还介绍了Redis在持久化时如何处理过期key。总体而言,本文对于想要深入了解缓存技术的读者具有一定的参考价值。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《后端工程师的高阶面经》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(5)

  • 最新
  • 精选
  • penbox
    感觉最后的那个预加载案例实际生活中还是比较多的。 比如说点开一篇文章,只会返回文字,文章中的图片只有浏览到了相应的位置之后才会加载出来。但是等浏览到图片的实际显示位置才开始加载图片,图片显示的速度就可能很慢。所以实际的图片加载的位置会提前一些。 还有就是比如查看朋友圈的九宫格图片,点开了第一张大图,多半还会打开后面几张。那么就可以先预加载第二张第三张,等真的打开第二张的时候,又继续预加载第四张。 预加载这种思路,在用户行为可预期的情况下,可以做到既提高用户的使用体验,又不过多地占用服务资源。

    作者回复: 是的。不过这个代码写起来麻烦。

    2023-09-03归属地:四川
    2
  • 程序员花卷
    我在 xxx 零售项目中,为了应对高并发的抢购场景,进一步提高系统的性能,采用了多级缓存即 "本地缓存 + Redis 缓存 + 数据库 "的缓存方案,让本地缓存抗住大流量,Redis 缓存次之,数据库兜底。主要是针对读操作的接口做缓存设计,将抢购活动列表、抢购活动详情、抢购商品列表以及抢购商品详情放到了本地缓存和 Redis 缓存,这些数据在我们平台中都属于热点数据,如何给这些热点数据设置缓存过期时间就尤为重要了,设置短了,命中率低,大量的流量都会打在数据库上;设置长了,会浪费内存空间。 我们最终是以抢购活动时间来作为缓存过期时间的,假设运营那边添加了一个抢购活动并且持续时间是 2 小时,那么这些数据我们设置的过期时间基本都是 2 小时左右,因为一旦抢购活动结束,这些数据都可能不再是热点数据。为了释放内存,所以会将其清理。 我这么回答OK不,老师,哈哈

    作者回复: 可以。但是还可以更加高级。 考虑到缓存的数据很多,我们结合了哈希负载均衡和本地缓存。例如说某个特定的商品的信息,一定在特定的节点的本地缓存上,这样可以提高本地缓存的命中率,减少缓存的消耗。 更加好可以是,在抢购的时候,我们的直接不允许这个阶段参与抢购的商品修改,因此我们可以将缓存前置到 BFF (搞 CDN 都可以,或者静态页面)……

    2023-12-09归属地:云南
    2
  • ZhiguoXue_IT
    1)本地缓存的场景,我们绑定映射关系是用的是本地的hashmap,我理解在调用remove方法的时候,进行删除当前的key哇 2)之前12点有电商流量进来,如果大量缓存过期,会出现缓存雪崩的现象,我们一般都加上随机过期时间

    作者回复: 赞!

    2023-09-30归属地:山西
  • god_like
    老师 最后的思维导图有几处错误,辛苦更正下哈

    编辑回复: 可以详细说说哪里有错误吗,我们看一下

    2023-08-31归属地:北京
    2
  • peter
    请教老师几个问题: Q1:延迟队列这种方式是什么时候放入队列? 实现过期机制的四种方式中,对于延迟队列,对象是过期以后放入队列吗?还是一开始就放入队列? Q2:Redis的定期删除,是自身实现的?还是依靠外部程序实现的? (自身实现是指Redis通过设置某个参数等操作来实现;依靠外部程序实现是指Redis之外的一个程序来定期扫描Redis从而删除) Q3:遍历DB是指Redis而不是MySQL吧。 文中遍历的DB0、DB1等等,是Redis自身划分的几个区域,而不是指真正的数据库比如MySQL吧。 Q4: Redis删除过期key时,遍历的执行时间一般设置多大?

    作者回复: 1. 设置键值对的时候就要放进去,Set 方法的时候 2. 自身实现的 3. Redis 的 DB,不是 MySQL 4. 看我对 hz 的描述。一般如果你没把握就不要调整,直接使用默认值。或者,你去问你家运维,他们可能调过。

    2023-08-30归属地:北京
收起评论
显示
设置
留言
5
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部