百度360必应搜狗淘宝本站头条
当前位置:网站首页 > IT技术 > 正文

「每天一道面试题」Redis过期策略及实现原理

wptr33 2024-12-17 16:47 37 浏览

Redis过期策略及实现原理

描述

我们在使用 Redis 时,一般会设置一个过期时间,当然也有不设置过期时间的,也就是永久不过期。当我们设置了过期时间,Redis 是如何判断是否过期,以及根据什么策略来进行删除的。

redis过期时间设置

语法

# 以秒为单位设置过期,这是最常用的方式
EXPIRE KEY time

# 字符串独有的方式
SETEX KEY_NAME TIMEOUT VALUE

说明

除了 字符串 自己独有设置过期时间的方法外,其他方法都需要依靠 EXPIRE 方法来设置时间,如果没有设置时间,那缓存就是永不过期。

如果设置了过期时间,之后又想让缓存永不过期,使用 persist KEY

三种过期策略

定时删除

含义

在设置 KEY 的过期时间的同时,为该 KEY 创建一个定时器,让定时器在 KEY 的过期时间来临时,对 KEY 进行删除。

优点

该方法可以保证内存被尽快释放。

缺点

若过期 KEY 很多,删除这些 KEY 会占用很多的 CPU 时间,在 CPU 时间紧张的情况下,CPU 不能把所有的时间用来做要紧的事儿,还需要去花时间删除这些 KEY。

定时器的创建耗时,若为每一个设置过期时间的 KEY 创建一个定时器(将会有大量的定时器产生),性能影响严重。

懒汉式删除

含义

KEY 过期的时候不删除,每次通过 KEY 获取值的时候去检查是否过期,若过期,则删除,返回 null。

优点

删除操作只发生在通过 KEY 取值的时候,而且只删除当前 KEY,所以对 CPU 时间的占用是比较少的,而且此时的删除是已经到了非做不可的地步(如果此时还不删除的话,我们就会获取到了已经过期的 KEY 了)。

缺点

若大量的 KEY 在超出超时时间后,很久一段时间内,都没有被获取过,那么可能发生内存泄露(无用的垃圾占用了大量的内存)。

定期删除

含义

每隔一段时间执行一次删除过期 KEY 操作。

优点

通过限制删除操作的时长和频率,来减少删除操作对 CPU 时间的占用。

缺点

在内存友好方面,不如 ”定时删除”(会造成一定的内存占用,但是没有懒汉式那么占用内存),在 CPU 时间友好方面,不如 ”懒汉式删除”(会定期的去进行比较和删除操作,cpu 方面不如懒汉式,但是比定时好)。

难点是合理设置删除操作的执行时长(每次删除执行多长时间)和执行频率(每隔多长时间做一次删除)(这个要根据服务器运行情况来定了),每次执行时间太长,或者执行频率太高对 cpu 都是一种压力。每次进行定期删除操作执行之后,需要记录遍历循环到了哪个标志位,以便下一次定期时间来时,从上次位置开始进行循环遍历。

说明

memcached 只是用了惰性删除,而 redis 同时使用了惰性删除与定期删除,这也是二者的一个不同点(可以看做是 redis 优于 memcached 的一点)。

对于懒汉式删除而言,并不是只有获取 KEY 的时候才会检查 KEY 是否过期,在某些设置 KEY 的方法上也会检查,比如 SETNEX 命令,因为 SETNX 命令是在 KEY 不存在的情况下才设置,因为,如果不做过期 KEY 检查,那么直接设置,就会与我们原来的意思相违背。

定时任务

单线程的 redis,如何知道要运行定时任务?

redis 是单线程的,线程不但要处理定时任务,还要处理客户端请求,线程不能阻塞在定时任务或处理客户端请求上,那么,redis 是如何知道何时该运行定时任务的呢?

Redis 的定时任务会记录在一个称为最小堆的数据结构中。这个堆中,最快要执行的任务排在堆的最上方。在每个循环周期,Redis 都会将最小堆里面已经到点的任务立即进行处理。处理完毕后,将最快要执行的任务还需要的时间记录下来,这个时间就是接下来处理客户端请求的最大时长,若达到了该时长,则暂时不处理客户端请求而去运行定时任务。

配置

Redis 中定期删除使用的是统一的一个定时器,定时器执行的时长默认为 10,具体配置如下:



提高它的值将会占用更多的 cpu,当然相应的 redis 将会更快的处理同时到期的许多 key,以及更精确的去处理超时。 hz 的取值范围是 1~500,通常不建议超过 100,只有在请求延时非常低的情况下可以将值提升到 100。

Redis采用的过期策略

说明

Redis 采用的是懒汉式删除+定期删除。

懒汉式删除流程

  1. 在进行 GET 或 SETNX 等操作时,先检查 KEY 是否过期;
  2. 若过期,删除 KEY,然后执行相应操作;
  3. 若没过期,直接执行相应操作;

定期删除流程

简单而言,对指定 N 个库的每一个库随机删除小于等于指定 M 个过期 KEY,具体流程如下:

  1. 遍历每个数据库(就是 redis.conf 中配置的 ”database” 数量,默认为 16)
  2. 检查当前库中的指定个数个 KEY(默认是每个库检查 20 个 KEY,注意相当于该循环执行 20 次,循环体是下边的描述)
  3. 如果当前库中没有一个 KEY 设置了过期时间,直接执行下一个库的遍历随机
  4. 获取一个设置了过期时间的 KEY,检查该 KEY 是否过期,如果过期,删除 KEY 判断定期删除操作是否已经达到指定时长,若已经达到,直接退出定期删除。

对于定期删除,在程序中有一个全局变量 current_db 来记录下一个将要遍历的库,假设有 16 个库,我们这一次定期删除遍历了 10 个,那此时的 current_db 就是 11,下一次定期删除就从第 11 个库开始遍历,假设 current_db 等于 15 了,那么之后遍历就再从 0 号库开始(此时 current_db==0)。

参考文章:嗨客网 Redis 过期策略及实现原理

相关推荐

什么是Java中的继承?如何实现继承?

什么是继承?...

Java 继承与多态:从基础到实战的深度解析

在面向对象编程(OOP)的三大支柱中,继承与多态是构建灵活、可复用代码的核心。无论是日常开发还是框架设计,这两个概念都扮演着至关重要的角色。本文将从基础概念出发,结合实例与图解,带你彻底搞懂Java...

Java基础教程:Java继承概述_java的继承

继承概述假如我们要定义如下类:学生类,老师类和工人类,分析如下。学生类属性:姓名,年龄行为:吃饭,睡觉老师类属性:姓名,年龄,薪水行为:吃饭,睡觉,教书班主任属性:姓名,年龄,薪水行为:吃饭,睡觉,管...

java4个技巧:从继承和覆盖,到最终的类和方法

日复一日,我们编写的大多数Java只使用了该语言全套功能的一小部分。我们实例化的每个流以及我们在实例变量前面加上的每个@Autowired注解都足以完成我们的大部分目标。然而,有些时候,我们必须求助于...

java:举例说明继承的概念_java继承的理解

在现实生活中,继承一般指的是子女继承父辈的财产。在程序中,继承描述的是事物之间的所属关系,通过继承可以使多种事物之间形成一种关系体系。例如猫和狗都属于动物,程序中便可以描述为猫和狗继承自动物,同理,...

从零开始构建一款开源的 Vibe Coding 产品 Week1Day4:业界调研之 Agent 横向对比

前情回顾前面两天我们重点调研了了一下Cursor的原理和Cursor中一个关键的工具edit_file的实现,但是其他CodingAgent也需要稍微摸一下底,看看有没有优秀之处,下...

学会这几个插件,让你的Notepad++使用起来更丝滑

搞程序开发的小伙伴相信对Notepad++都不会陌生,是一个占用空间少、打开启动快的文件编辑器,很多程序员喜欢使用Notepad++进行纯文本编辑或者脚本开发,但是Notepad++的功能绝不止于此,...

将 node_modules 目录放入 Git 仓库的优点

推荐一篇文章Whyyoushouldcheck-inyournodedependencies[1]...

再度加码AI编程,腾讯发布AI CLI并宣布CodeBuddy IDE开启公测

“再熬一年,90%的程序员可能再也用不着写for循环。”凌晨两点半,王工还在公司敲键盘。他手里那份需求文档写了足足六页,产品经理反复改了三次。放在过去,光数据库建表、接口对接、单元测试就得写两三天。现...

git 如何查看stash的内容_git查看ssh key

1.查看Stash列表首先,使用gitstashlist查看所有已保存的stash:...

6万星+ Git命令懒人必备!lazygit 终端UI神器,效率翻倍超顺手!

项目概览lazygit是一个基于终端的Git命令可视化工具,通过简易的TUI(文本用户界面)提升Git操作效率。开发者无需记忆复杂命令,即可完成分支管理、提交、合并等操作。...

《Gemini CLI 实战系列》(一)Gemini CLI 入门:AI 上命令行的第一步

谷歌的Gemini模型最近热度很高,而它的...

deepin IDE新版发布:支持玲珑构建、增强AI智能化

IT之家8月7日消息,深度操作系统官方公众号昨日(8月6日)发布博文,更新推出新版deepin集成开发环境(IDE),重点支持玲珑构建。支持玲珑构建deepinIDE在本次重磅更...

狂揽82.7k的star,这款开源可视化神器,轻松创建流程图和图表

再不用Mermaid,你的技术文档可能已经在悄悄“腐烂”——图表版本对不上、同事改完没同步、评审会上被一句“这图哪来的”问得哑口无言。这不是危言耸听。GitHub2025年开发者报告显示,63%的新仓...

《Gemini CLI 实战系列》(五)打造专属命令行工具箱

在前几篇文章中,我们介绍了GeminiCLI的基础用法、效率提升、文件处理和与外部工具结合。今天我们进入第五篇...