Redis中的过期键删除策略

news2024/9/22 19:34:11

过期键删除策略

概述

数据库键的过期时间都保存在过期字典中,并且知道根据过期时间去判断一个键是否过期,剩下的问题是:如果一个键过期了,那么它什么时候会被删除呢?
这个问题有三种可能的答案,它们分别代表了三种不同的删除策略:

  • 1.定时删除:在是个照顾键的过期时间的同时,创建一个定时器(timer),让定时器在键的过期时间来临时,立即执行对键的删除操作
  • 2.惰性删除:放任键过期不管,每次从键空间中获取键时,检查取得的键是否过期,如果过期的话,就删除该键;如果没有过期,就返回该键
  • 3.定期删除:每隔一段时间,程序就对数据库进行一次检查,删除里面的过期键。至于要删除多少过期键,以及要检查多少个数据库,则由算法决定

在这三种策略中,第一种和第三种为主动删除策略,而第二种则为被动删除策略

定时删除

定时删除策略对内存时最优化的:通过使用定时器,定时删除策略可以保证过期键会尽快地被删除,并释放过期键所占用地内存。另一方面,定时删除策略的缺点就是,它是对CPU时间最不友好的,在过期键比较多的情况下,删除过期键这一行为可能会占用相当一部分CPU时间,在内存不紧张
但是CPU时间非常紧张的情况下,将CPU时间用在删除和当前任务无关的过期键上,无疑会对服务器的响应时间和吞吐量造成影响。

例子

例如,如果正有大量的命令请求在等待服务器处理,并且服务器当前不缺少内存,那么服务器应该优先将CPU时间用在处理客户端的命令请求上面,而不是用在删除过期键上面

除此之外,创建一个定时器需要用到Redis服务器中的时间事件,而当前事件事件的实现方式——无序链表,查找一个事件的事件复杂度为O(N)——并不能高效地处理大量时间事件。因此,要让服务器创建大量的定时器,从而实现定时删除策略,在现阶段来说并不现实

惰性删除

惰性删除策略对CPU事件来说是最友好的:程序只会在取出键时才对键进行过期检查,这可以保证删除过期键的操作只会在非做不可的情况下进行,并且删除的目标仅限当前处理的键,这个策略不会在删除其他无关的键上花费任何CPU事件。惰性删除的缺点是,它对内存是最不友好的,如果一个键已经过期,而这个键又仍然保留在数据库中,那么只要这个过期键不被删除,它所占用的内存就不会释放。在使用惰性删除策略时,如果数据库中有非常多的过期键,而这些过期键又恰好没有被访问到的话,
那么它们也许永远不会被删除(除非用户手动执行FLUSHDB),我们甚至可以将这种情况看作是一种内存泄漏——无用的垃圾数据占用了大量的内存,而服务器却不会自己去释放它们,这对于运行状态非常依赖于内存的Redis服务器来说,肯定不是一个好消息

例子

举个例子,对于一些和时间相关的数据,比如日志(log),在某个时间点之后,对他们的访问就会大大减少,甚至不再访问,如果这类过期数据大量地积压在数据库中,用户以为服务器已经自动将它们删除了,但实际上这些键仍然存在,而且键所占用地内存也没有放,那么造成的后果肯定是非常严重的。

定期删除。

从定时删除和惰性删除分析来看,这两种删除方式在单一使用时都有明显的缺陷:

  • 1.定时删除占用太多CPU时间,影响服务器的响应时间和吞吐量
  • 2.惰性删除浪费太多内存,有内存泄漏的危险

定期删除策略是前两种策略的一种整合折中:

  • 1.定期删除策略每隔一段时间执行一次删除过期操作,并通过限制删除操作执行的时长和频率来减少删除操作对CPU时间的影响
  • 2.除此之外,通过定期删除过期键,定期删除策略有效地减少了因为过期键而带来的内存浪费定期删除策略的难点是确定删除操作执行的时长和频率
  • 1.如果删除操作执行得太频繁,或者执行的时间太长,定期删除策略就会退化成定时删除策略,以至于将CPU时间过多地消耗在删除过期键上面
  • 2.如果删除操作执行得太少,或者执行的时间太短,定期删除策略又会和惰性删除策略一样,出现浪费内存的情况因此,如果采用定期删除策略的话,服务器必须根据情况,合理地设置删除操作地执行时长和执行频率

Redis的过期键删除策略使用?

概述

Redis服务器实际使用地是惰性删除和定期删除两种策略:通过配合使用这两种删除策略,服务器可以很好地在合理使用CPU时间和避免浪费内存空间之间取得平衡

惰性删除策略的实现

过期键的惰性删除策略由db.c/expireIfNeeded函数实现,所有读写数据库的Redis命令在执行之前都会调用expireIfNeed函数对输入键进行检查:

  • 1.如果输入键已经过期,那么expireIfNeeded函数将输入键从数据库中删除
  • 2.如果输入键未过期,那么expireIfNeeded函数不做动作
    另外,因为每个被访问的键都可能存在过期而被expireIfNeeded函数删除,所以每个命令的实现函数都必须同时处理键存在以及键不存在这两种情况:
  • 1.当键存在时,命令按照键存在的情况执行
  • 2.当键不存在或者因为过期而被expireIfNeeded函数删除时,命令按照键不存在的情况执行

命令调用expireIfNeeded函数的过程

在这里插入图片描述

expireIfNeeded函数就像一个过滤器,它可以在命令真正执行之前,过滤掉过期的输入键,从而避免命令接触到过期键。

例子

举个例子,如图所示展示了GET命令的执行过程,在这个执行过程中,命令需要判断键是否存在以及键是否过期,然后根据判断来执行合适的动作
在这里插入图片描述

定期删除策略的实现

过期键的定期删除策略由redis.c/activeExpireCycle函数实现,每当Redis的服务器周期性操作redis.c/serverCron函数执行时,activeExpireCycle函数就会被调用,它在规定的时间内分多次调用服务器中的各个数据库,从数据库的expires字典中随机检查一部分键的过期时间,并删除其中的过期键。伪代码实现如下

# 默认每次检查的数据库数量
DEFAULT_DB_NUMBERS = 16
# 默认每个数据库检查的键数据量
DEFAULT_KEY_NUMBERS = 20;

# 全局变量,记录检查进度
current_db= 0

def activeExpireCycle() :
 # 初始化要检查的数据库数量
 # 如果服务器的数据库数量比DEFAULT_DB_NUMBERS药效
 # 那么以服务器的数据库数量为准
 if server.dbnum < DEFAULT_DB_NUMBERS:
  db_numbers = server.dbnum
 else:
  db_numbers = DEFAULT_DB_NUMBERS
  
 
 # 遍历各个数据库
 for i in range(db_numbers):
  # 如果current_db的值等于服务器的数据库数量
  # 这表示检查程序已经遍历了服务器的所有数据库一次
  # 将current_db重置为0,开始新的一轮遍历
  if current_db = server.dbnum
   current_db = 0
  
  # 获取当前要处理的数据库
  redisDb = server.db[current_db]
  
  # 将数据库索引增1,指向下一个要处理的数据库
  current_db += 1
  
  # 检查数据库键
  for j in range(DEFAULT_KEY_NUMBERS):
   # 如果数据库中没有一个键带有过期时间,那么跳过这个数据库
   if redisDb.expires.size() == 0: break
   # 随机获取一个带有过期时间的键
   key_with_ttl = redisDb.expires.get_random_key()
   
   # 检查键是否过期,如果过期就删除它
   if is_expired(key_with_ttl):
    delete_key(key_with_ttl)
   # 已达到时间上线,停止处理
   if reach_time_limit() :return

流程概括

activeExpireCycle函数的工作模式可以总结如下:

  • 1.函数每次运行时,都从一定数量的数据库中取出一定数量的随机键进行检查,并删除其中的过期键
  • 2.全局变量current_db会记录当前activeExpireCycle函数检查的进度,在下一次activeExpireCycle函数被调用时,接着上一次的进度进行处理,比如说,如果当前activeExpireCycle函数在遍历10号数据库时返回了,那么下次activeExpireCycle函数执行时,将从11号数据库开始查找并删除过期键
  • 3.随着activeExpireCycle函数的不断执行,服务器中的所有数据库都会被检查一遍,这时函数将current_db变量重置为0,然后再次开始新一轮的检查工作

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1534877.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

阿里云国际该如何设置DDoS高防防护策略?

DDoS高防提供针对网络四层DDoS攻击的防护策略设置功能&#xff0c;例如虚假源和空连接检测、源限速、目的限速&#xff0c;适用于优化调整非网站业务的DDoS防护策略。在DDoS高防实例下添加端口转发规则&#xff0c;接入非网站业务后&#xff0c;您可以单独设置某个端口的DDoS防…

专题三 - 二分 - leetcode 704. 二分查找 | 简单难度

leetcode 704. 二分查找 leetcode 704. 二分查找 | 简单难度1. 题目详情1. 原题链接2. 基础框架 2. 解题思路1. 题目分析2. 算法原理3. 时间复杂度 3. 代码实现4. 知识与收获 leetcode 704. 二分查找 | 简单难度 1. 题目详情 给定一个 n 个元素有序的&#xff08;升序&#x…

3.3网安学习第三阶段第三周回顾(个人学习记录使用)

本周重点 ①渗透测试介绍 ②sqlmap注入扫描工具 ③XSS脚本注入 本周主要内容 ①渗透测试介绍 一、渗透测试 通过模拟黑客对系统进行攻击的手段或技术&#xff0c;在被测系统中发现漏洞的行为。除了提供漏洞之外&#xff0c;还需提供安全意见。 与黑站不同&#xff0c;渗…

仿牛客项目Day10——统一异常处理、记录日志

统一异常处理 在controller里创建advice包&#xff0c;创建ExceptionAdvice类 这个注解括号里面是指只扫描被Controller标注的bean 请求request、响应response、异常exception 普通请求和异步请求的区别在于传的是json还是html吗&#xff1f; 统一记录日志 面向切面编程&…

2024/03/21(网络编程·day7)

一、思维导图 二、 //定义删除函数 int do_delete(sqlite3 *ppDb) {int del_numb0;printf("请输入要删除的学生的学号:");scanf("%d",&del_numb);getchar();//准备sql语句char sql[128]"select *from Stu";sprintf(sql,"delete from …

RocketMQ 流存储解析:面向流场景的关键特性与典型案例

作者&#xff1a;林清山&#xff08;隆基&#xff09; 前言&#xff1a; 从初代开源消息队列崛起&#xff0c;到 PC 互联网、移动互联网爆发式发展&#xff0c;再到如今 IoT、云计算、云原生引领了新的技术趋势&#xff0c;消息中间件的发展已经走过了 30 多个年头。 目前&…

蓝桥杯-模拟-纸张尺寸

题目 思路 代码 qlist(str(input())) numint(q[1]) x,y1189,841 while num:num-1x//2if x<y:x,yy,x print(x) print(y)

关于安卓调用文件浏览器(一)打开并复制

背景 最近在做一个硬件产品&#xff0c;安卓应用开发。PM抽风&#xff0c;要求从app打开文件浏览器&#xff0c;跳转到指定目录&#xff0c;然后可以实现文件复制粘贴操作。 思考 从应用开发的角度看&#xff0c;从app打开系统文件浏览器并且选择文件&#xff0c;这是很常见…

牛客小白月赛86(D剪纸游戏)

题目链接:D-剪纸游戏_牛客小白月赛86 (nowcoder.com) 题目描述: 输入描述: 输入第一行包含两个空格分隔的整数分别代表 n 和 m。 接下来输入 n行&#xff0c;每行包含 m 个字符&#xff0c;代表残缺纸张。 保证&#xff1a; 1≤n,m≤10001 字符仅有 . 和 * 两种字符&#xf…

代码随想录算法训练营 DAY 16 | 104.二叉树最大深度 111.二叉树最小深度 222.完全二叉树的节点个数

104.二叉树最大深度 深度和高度 二叉树节点的深度&#xff1a;指从根节点到该节点的最长简单路径边的条数或者节点数&#xff08;取决于深度从0开始还是从1开始&#xff09;二叉树节点的高度&#xff1a;指从该节点到叶子节点的最长简单路径边的条数或者节点数&#xff08;取…

按键模拟精灵

按键模拟精灵功能简单&#xff1a; 1.添加模拟按键 2.删除模拟按键 3.开始模拟 4.停止模拟 适合简单的按键操作&#xff0c;有需要的可以点赞收藏关注我&#xff01;

315晚会:虚假的水军是怎样形成的?又要如何破解?

随着互联网的普及和发展&#xff0c;网络信息的传播已经成为了现代社会中不可或缺的一部分。然而&#xff0c;随之而来的是网络舆论的泛滥和虚假信息的肆意传播&#xff0c;这使得网络治理变得尤为重要。 2024年的315晚会&#xff0c;央视曝光了一种新型的水军制造手段&#x…

DXF™ 格式对象和图元——cad vba

在 DXF™ 格式中&#xff0c;对象的定义与图元的定义不同&#xff1a;对象没有图形表示&#xff0c;而图元则有图形表示。例如&#xff0c;词典是对象而不是图元。图元也称为图形对象&#xff0c;而对象称为非图形对象。 第七段中humbnail image&#xff0c;即&#xff1a;缩略…

【智能算法】海洋捕食者算法(MPA)原理及实现

目录 1.背景2.算法原理2.1算法思想2.2算法过程 3.结果展示4.参考文献 1.背景 2020年&#xff0c;Afshin Faramarzi 等人受到海洋生物适者生存启发&#xff0c;提出了海洋捕食者算法(Marine Predators Algorithm&#xff0c;MPA)。 2.算法原理 2.1算法思想 MPA根据模拟自然界…

图神经网络实战(2)——图论基础

图神经网络实战&#xff08;2&#xff09;——图论基础 0. 前言1. 图属性1.1 有向图和无向图1.2 加权图和非加权图1.3 连通图和非连通图1.4 其它图类型 2. 图概念2.1 基本对象2.2 图的度量指标2.2 邻接矩阵表示法 3. 图算法3.1 广度优先搜索3.2 深度优先搜索 小结系列链接 0. 前…

户外水质检测显示屏用于检测并显示各种水质数据

水质检测一直是环境保护和公共卫生领域的重要课题。随着科技的不断进步&#xff0c;水质检测设备也在不断更新换代。其中&#xff0c;水质检测显示屏作为一种新型的检测设备&#xff0c;为监测和显示各种水质数据提供了便利和高效的手段。 水质检测显示屏是一种集成了传感器、数…

tcp seq ack

seq&#xff08;Sequence Number&#xff09;&#xff1a;32bits&#xff0c;表示这个tcp包的序列号。tcp协议拼凑接收到的数据包时&#xff0c;根据seq来确定顺序&#xff0c;并且能够确定是否有数据包丢失。 ack&#xff08;Acknowledgment Number&#xff09;&#xff1a;3…

Python基础学习笔记(一)

Python简介 Python 语言是一种跨平台、开源、免费、解释型、面向对象、动态数据类型的高级程序设计语言。早期版本的 Python 被称作是 Python1&#xff1b;Python2 最后一个版本是 2.7&#xff1b;Python3 是目前最活跃的版 本&#xff0c;基本上新开发的 Python 代码都会支持…

Infoq:腾讯内容千亿级实时计算和规则引擎实践优化之路

1.系统背景 腾讯内容中台提供从内容生产、内容加工、内容分发、内容结算等全链路环节的一站式服务&#xff0c;在这个过程中&#xff0c;会产生大量的数据以及围绕这些数据衍生的实时流业务应用&#xff0c;如智能审核、运营决策、在线学习等&#xff0c;从底层去看这些内容生态…

SM4加密是什么?SM4算法在国密HTTPS协议中的作用

SM4加密算法是一种分组密码标准&#xff0c;由国家密码管理局于2012年3月21日发布&#xff0c;相关标准为“GM/T 0002-2012《SM4分组密码算法》&#xff0c;与国际上广泛使用的AES等算法类似&#xff0c;SM4同算法样用于保护数据的机密性&#xff0c;确保信息在传输过程中不被未…