当前位置: 首页 > news >正文

Redis过期key的删除策略

在 Redis 中,设置了过期时间的键在过期时间到达后,并不会立即从内存中删除。如果不是,那过期后到底什么时候被删除呢?

下面对这三种删除策略进行具体分析。

立即删除:

立即删除能够保证内存数据的及时性和空间的有效利用,但在处理大量过期键时,它可能会对系统性能产生负面影响。

优点

  • 立即删除确保过期键在其过期后立即从内存中删除,这样可以确保数据的最大新鲜度,避免了过期数据继续占用内存。
  • 内存释放也是立即删除的一个重要优点,因为删除过期键会立即释放其占用的内存空间,使得系统能够更有效地管理内存。

缺点

  • 立即删除操作会占用 CPU 时间,特别是在处理大量键时或者在 CPU 负载高的情况下。这可能会对同时进行的其他计算任务(如交集计算或排序)造成额外的压力。这种情况下,Redis 可能会在处理删除操作时对其他请求的响应速度产生一定的影响,尤其是在高并发情况下。
  • Redis 使用无序链表来管理设置了过期时间的键。这意味着在执行过期键的检查和删除时,时间复杂度为 O(n),其中 n 是设置了过期时间的键的数量。尽管时间复杂度为 O(n),但通常情况下,链表中的过期键数量不会非常大,因此 Redis 的性能通常仍然能够满足大多数实际需求。

综上所述,虽然立即删除能够提供数据的最大新鲜度和内存的即时释放,但在处理大量过期键时可能会对 CPU 产生较大的负载。

惰性删除:

惰性删除是指,当一个键过期后,如果客户端尝试访问这个键,Redis 会先检查键是否过期。如果过期了,Redis 不会立即删除它,而是返回一个空值(nil)或者特定的过期标记,表示键已经过期。当有客户端访问这个键时,Redis 才会删除它并释放内存空间。

所以惰性删除的缺点很明显:浪费内存。dict字典和expires字典都要保存这个键值的信息。特别是在处理像日志这样的按时间更新的数据时,它可能会导致内存浪费问题。

定时删除(volatile-ttl):

定时删除是指,Redis 会以一定的频率(默认每秒钟检查10次)执行定期删除操作。在定期删除过程中,Redis 会扫描数据库中的部分过期键,并删除其中的过期键。这样做可以及时释放内存空间,避免过多过期键导致的内存浪费。

定时删除是一个常见的折中方案,能够有效地平衡立即删除和惰性删除所带来的问题。

这种方法通过周期性地执行删除操作来管理过期数据,具有以下几个关键优势:

  • 控制CPU消耗:定时删除可以通过限制每次删除操作执行的时长和频率,从而减少对CPU的瞬时负载影响。相比于立即删除,它在执行删除操作时分摊了处理压力,更加稳定和可控。
  • 减少内存浪费:相对于惰性删除,定时删除能够更及时地清理过期数据,从而有效减少长时间未使用的数据占用的内存空间。尤其对于存储大量日志或临时数据的场景,这种方式能显著降低内存浪费。
  • 可调节性:定时删除的执行频率和处理时长可以根据具体应用的需求进行调整。可以根据数据更新频率、过期数据的访问模式以及系统的整体负载情况来动态调整定时删除的策略,以达到最佳的性能和资源利用率。
  • 实现方式:在Redis中,可以通过定时任务(如使用Cron表达式)或者定时执行的后台任务来实现定时删除。也可以结合Redis的过期事件通知功能,使得过期数据的清理更加高效和即时。

总之,定时删除在实际应用中是一个非常有效的策略,特别适用于需要平衡CPU负载和内存利用的场景。通过合理配置删除频率和操作时长,可以最大程度地优化系统的整体性能和资源利用效率。

Redis使用的策略

Redis 使用的是一种结合了惰性删除定期删除的过期键值删除策略,这种方式旨在平衡性能和资源利用的效率。

这两种删除策略的结合,使得Redis能够在保证内存空间高效利用的同时,避免了单次大规模删除操作可能带来的性能问题。惰性删除保证了操作的即时响应性,而定期删除则定期清理已过期的键,防止过期键占用过多内存。

总结

  • 惰性删除:减少了性能开销,但可能导致内存浪费。
  • 定期删除:定期清理过期键,平衡性能和内存利用。
  • 立即删除:实时性高但性能开销大。

springboot+Redis的dome

1、引入依赖

首先,在 pom.xml 文件中添加 Spring Data Redis 的依赖:

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId>
</dependency>

2、配置 Redis

在 application.yml文件中配置 Redis 连接:

spring:data:redis:host: localhostport: 6379database: 0password: # 密码(默认为空)

3、配置 RedisTemplate

创建一个配置类来配置 RedisTemplate:

package com.example.demo.config;import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;@Configuration
public class RedisConfig {/*** 配置 RedisTemplate* 使用 StringRedisSerializer 序列化和反序列化 redis 的 key 值* 使用 GenericJackson2JsonRedisSerializer 序列化和反序列化 redis 的 value 值** @param redisConnectionFactory Redis 连接工厂* @return 配置好的 RedisTemplate*/@Beanpublic RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {RedisTemplate<String, Object> template = new RedisTemplate<>();template.setConnectionFactory(redisConnectionFactory);// 设置 key 和 Hash 的 key 序列化器为 StringRedisSerializertemplate.setKeySerializer(new StringRedisSerializer());template.setHashKeySerializer(new StringRedisSerializer());// 设置 value 和 Hash 的 value 序列化器为 GenericJackson2JsonRedisSerializertemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());template.setHashValueSerializer(new GenericJackson2JsonRedisSerializer());// 初始化 RedisTemplatetemplate.afterPropertiesSet();return template;}
}

4、使用 Redis 设置键的过期时间

创建一个简单的服务类来处理 Redis 操作:

package com.example.demo.service;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;import java.util.concurrent.TimeUnit;/*** Redis服务类,用于处理Redis相关的操作*/
@Service
public class RedisService {/*** RedisTemplate用于操作Redis,支持各种数据类型的存储和读取*/@Autowiredprivate RedisTemplate<String, Object> redisTemplate;/*** 设置键值对,并指定过期时间** @param key 键* @param value 值* @param timeout 过期时间* @param unit 过期时间单位*/public void setValueWithExpiration(String key, Object value, long timeout, TimeUnit unit) {redisTemplate.opsForValue().set(key, value, timeout, unit);}/*** 根据键获取值** @param key 键* @return 对应的值,如果不存在返回null*/public Object getValue(String key) {return redisTemplate.opsForValue().get(key);}/*** 删除指定键** @param key 要删除的键*/public void deleteValue(String key) {redisTemplate.delete(key);}
}

5、创建控制器来测试

创建一个简单的控制器来测试 Redis 过期键:

package com.example.demo.controller;import com.example.demo.service.RedisService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;import java.util.concurrent.TimeUnit;/*** Redis控制器,用于处理Redis相关的HTTP请求*/
@RestController
@RequestMapping("/redis")
public class RedisController {/*** 注入Redis服务,用于执行Redis操作*/@Autowiredprivate RedisService redisService;/*** 设置Redis键值对并指定过期时间** @param key    要设置的键* @param value  键的值* @param timeout 过期时间(秒),键将在指定秒数后自动删除* @return 响应实体,包含设置结果的信息*/@GetMapping("/set")public ResponseEntity<String> setKey(@RequestParam String key, @RequestParam String value, @RequestParam long timeout) {redisService.setValueWithExpiration(key, value, timeout, TimeUnit.SECONDS);return ResponseEntity.ok("键已设置,并将于 " + timeout + " 秒后过期");}/*** 获取Redis中的键值** @param key 要获取的键* @return 响应实体,包含键的值或相应提示信息*/@GetMapping("/get")public ResponseEntity<Object> getKey(@RequestParam String key) {Object value = redisService.getValue(key);if (value == null) {return ResponseEntity.ok("键不存在或已过期");}return ResponseEntity.ok(value);}/*** 删除Redis中的键** @param key 要删除的键* @return 响应实体,包含删除结果的信息*/@GetMapping("/delete")public ResponseEntity<String> deleteKey(@RequestParam String key) {redisService.deleteValue(key);return ResponseEntity.ok("键已删除");}
}

6、测试应用程序

启动 Spring Boot 应用程序,并通过以下 URL 测试 Redis 过期键:

设置键并指定过期时间(例如 10 秒):http://localhost:8080/redis/set?key=testKey&value=testValue&timeout=10

  • 响应: "键已设置,并将于 10 秒后过期"

获取键的值:http://localhost:8080/redis/get?key=testKey

  • 如果键存在: 返回键的值
  • 如果键不存在或已过期: "键不存在或已过期"

删除键:http://localhost:8080/redis/delete?key=testKey

  • 响应: "键已删除"

相关文章:

Redis过期key的删除策略

在 Redis 中&#xff0c;设置了过期时间的键在过期时间到达后&#xff0c;并不会立即从内存中删除。如果不是&#xff0c;那过期后到底什么时候被删除呢&#xff1f; 下面对这三种删除策略进行具体分析。 立即删除&#xff1a; 立即删除能够保证内存数据的及时性和空间的有效…...

软件管理

设备挂载在目录下才可以读 挂载类似于将u盘插在电脑上 mount /dev/sr0 /opt/openeuler/ vim /etc/rc.d/rc.local #开机自运行脚本&#xff0c;将挂载命令写入脚本&#xff0c;并给这个脚本执行权限 chmod x /etc/rc.d/rc.local [rootlocalhost ~]# cd /etc/yum.repos.d/ […...

【2024】Datawhale AI夏令营 Task3笔记——Baseline2部分代码解读及初步上分思路

【2024】Datawhale AI夏令营 Task3笔记——Baseline2部分代码解读及初步上分思路 本文对可完成赛事“逻辑推理赛道&#xff1a;复杂推理能力评估”初赛的Baseline2部分关键代码进行详细解读&#xff0c;介绍Baseline2涉及的关键技术和初步上分思路。 Baseline2代码由Datawhal…...

软件测试——测试分类(超超超齐全版)

为什么要对软件测试进行分类 软件测试是软件⽣命周期中的⼀个重要环节&#xff0c;具有较⾼的复杂性&#xff0c;对于软件测试&#xff0c;可以从不同的⻆度加以分类&#xff0c;使开发者在软件开发过程中的不同层次、不同阶段对测试⼯作进⾏更好的执⾏和管理测试的分类⽅法。…...

深入解析 Go 语言 GMP 模型:并发编程的核心机制

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家&#xff1a;点击跳转到网站&#xff0c;对人工智能感兴趣的小伙伴可以点进去看看。 前言 本章是Go并发编程的起始篇章&#xff0c;在未来几篇文章中我们会…...

PHP中如何处理字符串

在PHP中&#xff0c;处理字符串是一项非常常见的任务&#xff0c;PHP提供了大量的内置函数来方便地处理字符串。以下是一些常用的字符串处理函数&#xff1a; strlen() - 返回字符串的长度。 php复制代码 $text "Hello, World!"; echo strlen($text); // 输出&…...

windows内存泄漏检查汇总

VLD(Visual Leak Detector) 下载 官方下载地址2.5 另一分支2.7 安装 点击运行安装...

yolo格式数据集之空中及地面拍摄道路病害检测7种数据集已划分好|可以直接使用|yolov5|v6|v7|v8|v9|v10通用

yolo格式数据集之空中及地面拍摄道路病害检测7种数据集已划分好|可以直接使用|yolov5|v6|v7|v8|v9|v10通用 本数据为空中及地面拍摄道路病害检测检测数据集&#xff0c;数据集数量如下&#xff1a; 总共有:33585张 训练集&#xff1a;6798张 验证集&#xff1a;3284张 测试集&a…...

[Meachines] [Easy] Mirai Raspberry树莓派默认用户登录+USB挂载文件读取

信息收集 IP AddressOpening Ports10.10.10.48TCP:22,53,80,1276,32400,32469 $ nmap -p- 10.10.10.48 --min-rate 1000 -sC -sV PORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH 6.7p1 Debian 5deb8u3 (protocol 2.0) | ssh-hostkey: | 1024 aa:ef:5c:…...

从零开始安装Jupyter Notebook和Jupyter Lab图文教程

前言 随着人工智能热浪&#xff08;机器学习、深度学习、卷积神经网络、强化学习、AGC以及大语言模型LLM, 真的是一浪又一浪&#xff09;的兴起&#xff0c;小伙伴们Python学习的热情达到了空前的高度。当我20年前接触Python的时候&#xff0c;做梦也没有想到Python会发展得怎么…...

数据库魔法:SQL Server中自定义分区函数的奥秘

数据库魔法&#xff1a;SQL Server中自定义分区函数的奥秘 在SQL Server中&#xff0c;分区表是管理大型表和提高查询性能的强大工具。分区函数和分区方案允许你根据特定的规则将数据分散到不同的文件组中。本文将深入探讨如何在SQL Server中实现数据库的自定义分区函数&#…...

网页禁止移除水印

一般的话水印分为明水印和暗水印两种 明水印的话就是在视频canvas上面蒙上一个div&#xff08;如我上篇文章&#xff09; &#xff0c;暗水印的话就是把文字通过技术嵌入到图像里。 具体实现的话可以使用MutationObserver API 来监视 DOM 的变化&#xff0c;特别是针对目标节…...

Node Red 与axios简易测试环境的搭建

为了学习在vue3中如何使用axios&#xff0c;我借Sider Fusion的帮助搭建了基于node的简易测试环境。 Axios 是一个基于 Promise 的 HTTP 客户端&#xff0c;通常用于浏览器环境&#xff0c;但它也可以在 Node.js 环境中使用。因此&#xff0c;可以在 Ubuntu 的 Bash 环境下通过…...

测试面试宝典(四十三)—— 接口测试流程

回答一&#xff1a; 接口测试一般遵循以下流程&#xff1a; 需求分析 仔细研究接口的需求文档&#xff0c;包括接口的功能、输入输出参数、业务逻辑、性能要求等。与开发人员、产品经理等沟通&#xff0c;确保对需求的理解准确无误。 测试计划制定 确定测试的目标、范围和策略。…...

arkhamintelligence 请求头加密 X-Payload 完整逆向分析+自动化解决方案

大家好!我是爱摸鱼的小鸿,关注我,收看每期的编程干货。 逆向是爬虫工程师进阶必备技能,当我们遇到一个问题时可能会有多种解决途径,而如何做出最高效的抉择又需要经验的积累。本期文章将以实战的方式,带你详细地逆向分析 arkhamintelligence 请求头加密字段 X-Payload 的…...

Vue Router哈希模式和历史模式

Vue官方文档 哈希模式&#xff08;hash mode&#xff09; 特点 URL 格式&#xff1a;使用 # 符号分隔路径&#xff0c;哈希值之后的部分由客户端解析。 https://example.com/#/about无需服务器配置&#xff1a;哈希值部分不会被发送到服务器&#xff0c;因此不需要额外的服…...

Springboot实战:AI大模型+亮数据代理助力短视频时代

目录 前言1.如何入门亮数据1.1、注册登录1.2、注册账号1.3、登录1.4、购买静态住宅代理1.5、展示购买的代理 2. 使用Springboot、AI大模型构建系统2.1 使用Springboot、AI大模型构建爬虫2.2、在Springboot项目添加工具 3、编写代码&#xff0c;爬取视频素材3.1、代码里使用代理…...

Postman请求问题 connect ECONNREFUSED 127.0.0.1:80解决方法

问题描述&#xff1a; 解决方法&#xff1a; &#xff08;1&#xff09;点击file-settings &#xff08;2&#xff09;点击Proxy&#xff0c;并将右边的Use the system proxy 取消选中 &#xff08;3&#xff09;勾选use custom proxy configuration 这个8080是默认的&#xf…...

维护SQL Server数据库索引:保持性能的黄金法则

维护SQL Server数据库索引&#xff1a;保持性能的黄金法则 在SQL Server中&#xff0c;数据库索引是优化查询性能的关键工具。然而&#xff0c;随着数据的不断变化&#xff0c;索引可能会变得碎片化或过时&#xff0c;从而降低数据库性能。因此&#xff0c;定期维护索引是确保…...

nvm管理node版本问题处理集合

windows上通过nvm管理node版本&#xff0c;通过nvm安装node&#xff0c;报错了&#xff0c;信息&#xff1a; > Could not retrieve https://nodejs.org/dist/latest/SHASUMS256.txt. Get > https://nodejs.org/dist/latest/SHASUMS256.txt: dial tcp 104.20.23.46:443: …...

CTF show Web 红包题第六弹

提示 1.不是SQL注入 2.需要找关键源码 思路 进入页面发现是一个登录框&#xff0c;很难让人不联想到SQL注入&#xff0c;但提示都说了不是SQL注入&#xff0c;所以就不往这方面想了 ​ 先查看一下网页源码&#xff0c;发现一段JavaScript代码&#xff0c;有一个关键类ctfs…...

前端倒计时误差!

提示:记录工作中遇到的需求及解决办法 文章目录 前言一、误差从何而来?二、五大解决方案1. 动态校准法(基础版)2. Web Worker 计时3. 服务器时间同步4. Performance API 高精度计时5. 页面可见性API优化三、生产环境最佳实践四、终极解决方案架构前言 前几天听说公司某个项…...

基于服务器使用 apt 安装、配置 Nginx

&#x1f9fe; 一、查看可安装的 Nginx 版本 首先&#xff0c;你可以运行以下命令查看可用版本&#xff1a; apt-cache madison nginx-core输出示例&#xff1a; nginx-core | 1.18.0-6ubuntu14.6 | http://archive.ubuntu.com/ubuntu focal-updates/main amd64 Packages ng…...

Frozen-Flask :将 Flask 应用“冻结”为静态文件

Frozen-Flask 是一个用于将 Flask 应用“冻结”为静态文件的 Python 扩展。它的核心用途是&#xff1a;将一个 Flask Web 应用生成成纯静态 HTML 文件&#xff0c;从而可以部署到静态网站托管服务上&#xff0c;如 GitHub Pages、Netlify 或任何支持静态文件的网站服务器。 &am…...

第一篇:Agent2Agent (A2A) 协议——协作式人工智能的黎明

AI 领域的快速发展正在催生一个新时代&#xff0c;智能代理&#xff08;agents&#xff09;不再是孤立的个体&#xff0c;而是能够像一个数字团队一样协作。然而&#xff0c;当前 AI 生态系统的碎片化阻碍了这一愿景的实现&#xff0c;导致了“AI 巴别塔问题”——不同代理之间…...

佰力博科技与您探讨热释电测量的几种方法

热释电的测量主要涉及热释电系数的测定&#xff0c;这是表征热释电材料性能的重要参数。热释电系数的测量方法主要包括静态法、动态法和积分电荷法。其中&#xff0c;积分电荷法最为常用&#xff0c;其原理是通过测量在电容器上积累的热释电电荷&#xff0c;从而确定热释电系数…...

热烈祝贺埃文科技正式加入可信数据空间发展联盟

2025年4月29日&#xff0c;在福州举办的第八届数字中国建设峰会“可信数据空间分论坛”上&#xff0c;可信数据空间发展联盟正式宣告成立。国家数据局党组书记、局长刘烈宏出席并致辞&#xff0c;强调该联盟是推进全国一体化数据市场建设的关键抓手。 郑州埃文科技有限公司&am…...

在golang中如何将已安装的依赖降级处理,比如:将 go-ansible/v2@v2.2.0 更换为 go-ansible/@v1.1.7

在 Go 项目中降级 go-ansible 从 v2.2.0 到 v1.1.7 具体步骤&#xff1a; 第一步&#xff1a; 修改 go.mod 文件 // 原 v2 版本声明 require github.com/apenella/go-ansible/v2 v2.2.0 替换为&#xff1a; // 改为 v…...

2025年- H71-Lc179--39.组合总和(回溯,组合)--Java版

1.题目描述 2.思路 当前的元素可以重复使用。 &#xff08;1&#xff09;确定回溯算法函数的参数和返回值&#xff08;一般是void类型&#xff09; &#xff08;2&#xff09;因为是用递归实现的&#xff0c;所以我们要确定终止条件 &#xff08;3&#xff09;单层搜索逻辑 二…...

MySQL体系架构解析(三):MySQL目录与启动配置全解析

MySQL中的目录和文件 bin目录 在 MySQL 的安装目录下有一个特别重要的 bin 目录&#xff0c;这个目录下存放着许多可执行文件。与其他系统的可执行文件类似&#xff0c;这些可执行文件都是与服务器和客户端程序相关的。 启动MySQL服务器程序 在 UNIX 系统中&#xff0c;用…...