当前位置:首页 > 问答 > 正文

Redis里头数据过期怎么搞,有哪些常见的策略和场景分享

Redis里头的数据过期,说白了就是给存进去的数据设个“保质期”,时间一到,Redis就会自动把这条数据给清理掉,这样就不用我们手动去删,既能省下宝贵的内存空间,也能实现很多有用的功能,这功能在日常开发里用得特别多。

Redis是怎么实现过期的?(来源:Redis官方文档)

Redis主要是通过给每个键(key)单独设置一个过期时间戳来实现的,当你给一个key设置了过期时间,比如10秒,Redis就会在内部记录下这个key“死亡”的具体时间点,它会用一些策略来决定什么时候、用什么方式去检查并删除那些已经过期的key。

常见的过期删除策略(来源:经典缓存理论与Redis实现)

光记录下过期时间还不够,关键是怎么把过期的找出来并扔掉,Redis用了两种策略结合的办法,这算是它的一个核心设计。

  1. 惰性删除:这个最好理解,懒”办法,当客户端尝试去读取一个key的时候,Redis才会顺带检查一下这个key有没有过期,如果过期了,那就当场删除,然后告诉客户端“这个key不存在”,这个策略的优点是节约CPU,只在使用的时候才干活,但缺点也很明显,如果一个过期的key永远没人来访问,那它就会一直占着内存不释放,成了“垃圾数据”。

  2. 定期删除:为了解决惰性删除的缺点,Redis又加了个“闹钟”机制,它会每隔一段时间(默认是100毫秒一次,来源:Redis配置文件中hz参数的相关说明)就随机抽取一批设置了过期时间的key进行检查,如果发现有过期的,就删除掉,至于每次抽多少key、检查多少数据库,Redis有内部的算法来控制,目的是在CPU开销和内存释放之间取得一个平衡,这个策略相当于主动清理,防止内存被大量过期数据长期占用。

Redis把这两种策略结合起来用,惰性删除搞定那些被访问的过期key,定期删除来清理那些没人管的“僵尸”key,配合着来效果就不错。

常见的应用场景分享

知道了怎么搞,那在什么情况下会用这个功能呢?场景非常多。

  1. 用户登录凭证(Session存储):这是最经典的场景,用户登录成功后,服务器会生成一个唯一的token(令牌)存到Redis里,并把token返回给用户的浏览器,给这个token设置一个过期时间,比如30分钟,之后用户每次请求都带着这个token,服务器就来Redis查一下有没有、过没过期,来判断用户是不是处于登录状态,如果用户30分钟没任何操作,token自动过期被删除,就相当于自动“登出”了,既安全又省事。

  2. 手机验证码或限时优惠券:比如短信验证码通常5分钟内有效,发完验证码后,就把手机号和对应的验证码存到Redis,设置5分钟过期,用户输入验证码时,一查便知对错和是否超时,时间一到,数据自动消失,完全不用写定时任务去清理,限时优惠券、秒杀活动的资格令牌等,都是一个道理。

  3. 热点数据的临时缓存:为了减轻数据库的压力,我们经常把一些经常被查询的热点数据(比如新闻首页的文章列表)放到Redis里,但这些数据可能不是永远不变的,比如新闻会更新的,这时候可以给缓存设置一个相对较短的过期时间,比如5分钟,5分钟内,所有请求都直接从高速的Redis获取数据,速度飞快,5分钟后缓存失效,下一个请求会从数据库重新加载最新数据并再次缓存5分钟,这样既享受了缓存的速度优势,又能保证数据不会太旧。

  4. 频率限制(限流):防止恶意请求或者滥用接口,我们希望某个API每个IP地址一分钟内最多只能请求60次,可以在Redis里用这个IP当key, value记录请求次数,并设置一分钟过期,每次请求来了,就给这个key的值加1,如果一分钟内次数超过60,就拒绝请求,等一分钟时间到,key自动过期,计数从零开始,非常方便地实现了滑动时间窗口的限流。

  5. 分布式锁:在分布式系统里,多个服务实例可能需要竞争同一个资源(比如同时只能有一个服务去处理某个任务),这时候可以用Redis来实现一个简单的分布式锁,抢到锁的服务会设置一个key,并给它一个较短的过期时间(比如10秒),这样即使抢到锁的服务因为某种原因挂掉了,没能主动释放锁,这个锁也会在10秒后自动过期,其他服务就能继续获取,避免了系统“死锁”。

需要注意的地方

虽然过期功能很好用,但也有坑要注意,Redis的过期策略是惰性加定期,这意味着过期key的删除不是实时的、精确到秒的,在某些极端情况下,可能会有少量过期数据没有及时被清理掉,还在内存里多待了一小会儿,如果你的应用场景对“过期后立即消失”有极其严格的要求,可能需要自己再想想别的办法来保证,不能百分之百依赖这个机制,不过对于绝大多数场景,它已经足够可靠和高效了。

Redis的数据过期是一个非常实用且核心的功能,通过灵活设置过期时间,可以轻松实现缓存管理、会话控制、业务限流等多种需求,是用好Redis必须掌握的知识点。

Redis里头数据过期怎么搞,有哪些常见的策略和场景分享