Reids里怎么搞定定时过期还有多线程优化,redis那边的过期机制多线程也挺关键的
- 问答
- 2025-12-28 13:47:42
- 4
关于Redis如何处理键的定时过期以及相关的多线程优化机制,这部分内容确实是Redis内部实现中非常精妙和关键的一环,它不是我们通常理解的用多线程直接去检查和删除每一个过期键,而是采用了一种多策略结合、后台渐进式处理的巧妙方式。
Redis的过期键处理核心:惰性删除 + 定期删除

根据《Redis设计与实现》这本书以及Redis官方文档的说明,Redis并没有为每个过期键创建一个独立的计时器线程,那样做的话,当存在数百万个过期键时,会消耗巨大的内存和CPU资源,是完全不现实的,取而代之的是两种主要策略的结合:惰性删除 和 定期删除。
-
惰性删除 这是最简单也最直接的一种策略,它的逻辑是:只有当客户端尝试访问一个键的时候,Redis才会顺便检查这个键是否已经过期。 在执行任何读取或写入该键的命令(如
GET、HGET、SET等)之前,Redis会先查看该键的过期时间,如果发现键已经过期,那么Redis会立即删除这个键,然后才执行后续操作,或者对于读命令,直接返回空(nil)给客户端。
- 优点:非常省资源,过期键如果再也没有被访问,那么它就会一直留在内存里,直到被其他方式清理掉,不会消耗任何额外的CPU时间来主动检查它。
- 缺点:对内存不友好,如果有很多键过期后永远不再被访问,它们就会变成“僵尸键”,一直占用着内存空间,导致内存无法被释放,这是一种典型的内存泄漏现象,单靠惰性删除是远远不够的。
-
定期删除 为了解决惰性删除可能导致的内存泄漏问题,Redis引入了定期删除 策略,这个策略可以理解为一种“主动清理”,Redis会周期性地、随机地从设置了过期时间的键中抽取一部分样本进行检查,并删除其中已经过期的键。
- 执行过程:Redis服务器内部有一个定时任务(默认每秒运行10次,即每100毫秒一次),这个任务会做很多事情,其中就包括处理过期键,它不会遍历整个数据库,因为那样在键很多时会非常慢,导致服务暂停(阻塞),Instead,它每次执行时: a. 随机从过期键字典中抽取一定数量的键(比如20个)。 b. 检查这20个键是否过期,删除所有已过期的键。 c. 统计本轮删除的键数量,如果删除的比例超过25%(比如20个里面删了5个以上),说明过期键还很多,那就立即再重复一次步骤a和b(继续随机抽20个检查删除),如此循环,直到某一次删除的比例低于25%,或者总的执行时间超过了预设的时限(防止长时间阻塞),本次定期删除任务才结束。
- 优点:通过这种自适应、渐进式的扫描,可以在CPU消耗和内存释放之间取得一个很好的平衡,当过期键多时,它就多清理几轮;过期键少时,它就少清理甚至不清理,避免无谓的CPU开销。
多线程在过期机制中的角色(Redis 6.0及以上)

你提到的“多线程优化”非常关键,这里需要澄清一个常见的误解,在Redis 6.0版本之前,上述的惰性删除和定期删除操作,都是在Redis的主线程中执行的,这意味着,如果定期删除任务在一次循环中需要删除大量键(比如连续多轮删除),或者惰性删除时碰巧遇到一个很大的过期键(如一个包含百万元素的Hash键),主线程就会被这个删除操作占用一段时间,在这段时间内无法处理客户端的其他请求,造成所谓的“延迟毛刺”。
Redis 6.0引入的多线程,主要是为了优化网络I/O和命令解析,而不是为了并行执行命令,Redis的核心模型仍然是单线程处理命令,以保证原子性,这并不意味着多线程对过期机制没有帮助。
Redis在6.0版本及以后,将一些耗时的、非关键路径的删除操作移交给了后台线程(BIO线程) 来处理,这主要涉及两个方面:
- 异步惰性删除:对于一些特别大的键(判断标准可配置),当它们因惰性删除或定期删除被标记为需要删除时,Redis主线程不会再亲自去释放其内存,而是将这个“释放大键内存”的繁重任务封装成一个任务,扔给后台的BIO线程去慢慢处理,这样,主线程就能迅速返回去处理下一个客户端请求,极大地减少了因删除大键而产生的延迟。
- 异步文件关闭:与AOF、RDB持久化相关的文件描述符关闭操作,也被移到了后台线程。
总结一下多线程的关键作用:它并没有改变“检查键是否过期”的逻辑(检查动作仍在主线程),而是将“释放已过期键所占用的庞大内存”这个最耗时的苦力活,从主线程剥离出去,交给了后台线程异步完成。 这是一种典型的“主线程负责快速决策,后台线程负责重型操作”的优化思想。
Redis通过 “惰性删除” 和 “定期删除” 这两种互补的策略,高效地管理着键的过期,而多线程(特指Redis 6.0+的后台BIO线程)的引入,则是对这个机制的关键优化,它通过将最耗时的内存释放工作异步化,显著降低了过期机制对主线程性能的影响,从而提升了Redis在应对大量数据过期时的整体响应能力和稳定性,就是主线程负责判断“什么东西该扔”,然后叫来后台的“清洁工”线程去实际“扔掉”那些又大又重的东西,自己则继续忙更重要的事——接待客户(处理命令)。
本文由酒紫萱于2025-12-28发表在笙亿网络策划,如有疑问,请联系我们。
本文链接:http://waw.haoid.cn/wenda/70062.html
