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

Redis里怎么设置自动过期清理,配置那些东西比较实用和靠谱

在Redis里设置自动过期,主要依靠两个核心机制:一是对单个键设置生存时间,二是Redis服务器定期清理过期键的策略,下面分别详细说明。

为具体的键设置过期时间

这是最直接、最常用的方法,你可以给任何Redis键设定一个存活时间,就像给食物贴上保质期标签一样,时间一到,这个键就会被自动删除,这主要用于会话管理、缓存数据、临时锁等场景。

设置方法主要有以下几种:

  1. EXPIRE 命令:给一个已经存在的键设置过期时间,单位是秒。EXPIRE mykey 60 表示 mykey 在60秒后过期。
  2. SET 命令的扩展参数:在存入键值对时直接设置过期时间,这是更推荐的做法,因为它是一个原子操作,有两种方式:
    • SET mykey "somevalue" EX 10:设置键值对,并在10秒后过期。
    • SET mykey "somevalue" PX 10000:设置键值对,并在10000毫秒后过期。
  3. PEXPIRE 命令:与EXPIRE类似,但时间单位是毫秒,精度更高。
  4. 设置过期时间点:除了设置存活时长,还可以指定一个具体的Unix时间戳让键过期。
    • EXPIREAT mykey 1719504000:在Unix时间戳1719504000(2024年6月28日0时0分0秒)过期。
    • PEXPIREAT mykey 1719504000000:同上,但时间戳精确到毫秒。

关键点:你可以使用 TTL mykeyPTTL mykey 命令来查询一个键还剩余多少秒或毫秒存活,如果返回-2,表示键不存在(已过期或被删除);如果返回-1,表示键存在但没有设置过期时间。

Redis服务器的过期清理策略(主动淘汰)

仅仅给键设置过期时间是不够的,还需要Redis服务器本身有一个“保洁员”来真正执行删除操作,这个保洁员的工作方式就是Redis的过期策略,它结合了两种方法,这在Redis官方文档中有明确说明(参考来源:Redis官方文档关于过期Expiration的章节)。

  1. 惰性删除

    • 工作机制:当客户端尝试访问一个键时,Redis会先检查这个键是否已过期,如果过期了,就立刻删除它,然后返回空值或错误,就像这个键从未存在过一样。
    • 优点:对CPU友好,只在必要时才进行检查和删除,不会占用额外的计算资源。
    • 缺点:对内存不友好,如果一个过期键再也没有被访问,那么即使它早已过期,也会一直占用着内存空间,相当于内存泄漏,这是内存浪费的主要来源。
  2. 定期删除

    • 工作机制:Redis会每隔一段时间(默认是每秒10次,可通过hz配置调整)随机抽取一部分设置了过期时间的键,检查它们是否过期,如果过期了就删除,每次抽检的键的数量由配置决定。
    • 优点:通过定期扫描,可以清理掉那些“僵尸”键(已过期但不再被访问的键),减少内存的无效占用。
    • 缺点:如果抽检的键数量太少或者频率太低,还是会有很多过期键残留;如果太激进,又会占用过多CPU,影响正常服务,这是一个需要权衡的点。

重要提示:Redis的自动过期清理是惰性删除 + 定期删除两者协同工作的结果,单靠任何一种都不完美,结合使用才能达到相对平衡的效果。

实用且靠谱的配置建议

了解了原理后,我们可以通过调整Redis的配置文件(redis.conf)来优化清理行为,使其更符合我们的实际需求,以下是一些非常实用的配置项:

  1. maxmemory:这是最重要的配置,你必须设置一个最大内存限制,当内存使用达到这个上限时,Redis会触发内存淘汰策略,这会强制删除一些键(包括可能未过期的键)来腾出空间,如果不设置这个值,Redis会一直占用内存直到被系统杀死。

  2. maxmemory-policy:这个配置决定了当内存达到maxmemory上限时,Redis会选择删除哪些键,这是保证服务可靠性的关键,常用的策略有:

    • volatile-lru最常用、最推荐的策略,只从设置了过期时间的键中,淘汰最近最少使用的键,这非常适合缓存场景,既保护了可能存在的永久数据,又优先清理了不常用的缓存。
    • allkeys-lru:从所有键中淘汰最近最少使用的键,如果你的应用将所有数据都视为缓存,可以用这个。
    • volatile-ttl非常实用的策略,从设置了过期时间的键中,淘汰剩余存活时间最短的键,这相当于优先清理“马上就要过期”的数据,很符合直觉。
    • noeviction:不淘汰任何键,当内存不足时,新写入操作会返回错误,适用于对数据一致性要求极高、不允许丢失任何数据的场景,但风险是会导致服务不可写。

    选择建议:对于大多数缓存应用,volatile-lruvolatile-ttl是比较安全靠谱的选择。

  3. hz:这个值默认是10,表示每秒执行定期删除的频率,提高这个值(比如到20)会让Redis更频繁地扫描并清理过期键,从而减少内存浪费,但也会增加CPU负担,如果你的服务器上过期键非常多,且内存紧张,可以适当调高它,如果CPU已经是瓶颈,则保持默认。

总结一下操作流程

  1. 规划内存:根据服务器资源,在redis.conf中合理设置 maxmemory
  2. 选择策略:根据业务类型(全是缓存还是混合数据),在redis.conf中设置 maxmemory-policy,通常选 volatile-lru
  3. 设置过期:在编写应用代码时,对所有缓存类、会话类数据,使用带EX/PX参数的SET命令,为其赋予合理的过期时间。
  4. 监控调整:观察Redis的内存使用情况和CPU负载,如果发现过期键清理不及时导致内存居高不下,且CPU有余量,可以考虑适度调高 hz 值。

通过以上组合拳,你就能在Redis中建立起一套实用且靠谱的自动过期清理机制,有效防止内存无限增长,保障服务的稳定性。

Redis里怎么设置自动过期清理,配置那些东西比较实用和靠谱