Java 中 Redis 过期策略深度解析(含拓展-redis内存淘汰策略列举)

🤟致敬读者

  • 🟩感谢阅读🟦笑口常开🟪生日快乐⬛早点睡觉

📘博主相关

  • 🟧博主信息🟨博客首页🟫专栏推荐🟥活动信息

文章目录

      • Java 中 Redis 过期策略深度解析
        • 一、Redis 过期策略核心原理回顾
        • 二、Java 中的过期操作 API
          • 1. Jedis 客户端操作
          • 2. Spring Data Redis 操作
        • 三、Java 中的策略实践要点
          • 1. 过期时间设置策略
          • 2. 大Key过期优化
          • 3. 缓存穿透/击穿防护
        • 四、生产环境最佳实践
          • 1. 过期键监控
          • 2. 动态调整策略
          • 3. 集群环境注意事项
        • 五、常见问题排查
          • 1. 内存未释放问题
          • 2. 过期键未删除问题
        • 六、高级特性应用
          • 1. Redisson 过期监听
          • 2. RedisJSON 过期扩展
      • 总结:Java 开发者必备技能
    • 拓展(Redis内存淘汰策略列举)
      • noeviction 默认的
      • volatile-lru
      • volatile-ttl
      • volatile-random
      • allkeys-lru
      • allkeys-random


📃文章前言

  • 🔷文章均为学习工作中整理的笔记。
  • 🔶如有错误请指正,共同学习进步。

Java 中 Redis 过期策略深度解析

在这里插入图片描述

在 Java 应用中,Redis 的过期策略是缓存管理的核心机制,直接关系到内存使用效率和系统性能。下面从原理到实践全面解析:


一、Redis 过期策略核心原理回顾
  1. 双重删除策略

    • 惰性删除:访问时检查过期时间,若过期则立即删除
    • 定期删除:Redis 每秒执行 10 次(可配置)的过期扫描
      # redis.conf 配置
      hz 10  # 每秒扫描频率
      
  2. 内存淘汰机制

    内存达到 maxmemory
    淘汰策略
    volatile-lru
    volatile-ttl
    volatile-random
    allkeys-lru
    noeviction

二、Java 中的过期操作 API
1. Jedis 客户端操作
// 设置键值对并指定过期时间(秒)
jedis.setex("user:session:1001", 1800, "session_data"); // 单独设置过期时间
jedis.expire("cache:product:2023", 3600);  // 秒
jedis.pexpire("temp:data", 5000L);         // 毫秒// 获取剩余时间
long ttl = jedis.ttl("user:session:1001"); // 秒
long pttl = jedis.pttl("cache:product:2023"); // 毫秒
2. Spring Data Redis 操作
// 注解方式设置缓存过期
@Cacheable(value = "users", key = "#userId", cacheManager = "customCacheManager")
public User getUser(String userId) {// ...
}// 配置自定义 CacheManager
@Bean
public RedisCacheManager customCacheManager(RedisConnectionFactory factory) {RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofMinutes(30)) // 全局默认30分钟.serializeValuesWith(SerializationPair.fromSerializer(new Jackson2JsonRedisSerializer<>(User.class)));return RedisCacheManager.builder(factory).cacheDefaults(config).withCacheConfiguration("users", RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofHours(2))) // 特定缓存2小时.build();
}

三、Java 中的策略实践要点
1. 过期时间设置策略
  • 动态 TTL:避免缓存雪崩

    // 基础过期时间 + 随机偏移量
    int baseExpire = 3600; // 1小时
    int randomOffset = new Random().nextInt(600); // 0-10分钟随机
    jedis.setex("hot_product", baseExpire + randomOffset, productData);
    
  • 分级过期

    数据类型建议 TTL说明
    用户会话30-60分钟高安全性要求
    商品详情2-4小时中等更新频率
    全局配置永久(不设)极少变更
2. 大Key过期优化

Redis 6.0+ 异步删除配置:

// 启动Redis时配置异步删除
new RedisServer("redis-server", "--lazyfree-lazy-expire yes","--lazyfree-lazy-eviction yes");// Redisson 处理大Hash
RMapCache<String, Product> map = redisson.getMapCache("products");
map.expire(2, TimeUnit.HOURS); // 整个Map过期
3. 缓存穿透/击穿防护
// 双重检查锁解决缓存击穿
public Product getProduct(String id) {String key = "product:" + id;String data = jedis.get(key);if ("".equals(data)) return null; // 空值缓存if (data == null) {synchronized (this) {data = jedis.get(key);if (data == null) {Product product = db.getProduct(id);if (product == null) {jedis.setex(key, 300, ""); // 空值缓存5分钟return null;}jedis.setex(key, 3600, serialize(product));return product;}}}return deserialize(data);
}

四、生产环境最佳实践
1. 过期键监控
// 获取Redis统计信息
String stats = jedis.info("stats");
Pattern pattern = Pattern.compile("expired_keys:(\\d+)");
Matcher matcher = pattern.matcher(stats);
if (matcher.find()) {long expiredKeys = Long.parseLong(matcher.group(1));metrics.record("redis.expired_keys", expiredKeys);
}// Spring Boot Actuator 监控
@Bean
public MeterRegistryCustomizer<MeterRegistry> redisMetrics() {return registry -> {registry.gauge("redis.expired_keys", Tags.of("host", redisHost),() -> jedis.info("stats").contains("expired_keys:") ? Long.parseLong(jedis.info("stats").split("expired_keys:")[1].split("\r")[0]) : 0);};
}
2. 动态调整策略
// 根据负载动态调整过期时间
int getDynamicTTL() {double load = getSystemLoad();if (load > 0.8) return 600;   // 高负载时缩短TTLif (load < 0.3) return 3600;  // 低负载时延长TTLreturn 1800;                  // 默认30分钟
}jedis.setex("cache:data", getDynamicTTL(), data);
3. 集群环境注意事项
  • 主从延迟:主节点删除后从节点可能短暂存在过期数据
    // 强制读主节点解决脏读
    if (consistencyRequired) {jedis.readonly(); // 关闭只读模式(默认从主节点读)
    }
    
  • 跨数据中心:使用 Redisson 的 RRemoteService
    RRemoteService remoteService = redisson.getRemoteService();
    remoteService.register(ProductService.class, productServiceImpl, RemoteInvocationOptions.defaults().timeout(3, TimeUnit.SECONDS));
    

五、常见问题排查
1. 内存未释放问题

现象INFO memory 显示内存未减少
排查步骤

  1. 检查 maxmemory-policy 配置
  2. 监控 evicted_keysexpired_keys 计数器
  3. 使用 redis-cli --bigkeys 分析大Key
  4. 检查是否启用异步删除(Redis 6.0+)
2. 过期键未删除问题

原因

  • 键长期未被访问(惰性删除未触发)
  • 定期删除扫描未命中(概率性遗漏)
  • 主从同步延迟

解决方案

// 主动触发过期扫描(生产慎用)
jedis.configSet("hz", 100);  // 临时提高扫描频率
Thread.sleep(5000);          // 等待5秒
jedis.configSet("hz", 10);   // 恢复默认

六、高级特性应用
1. Redisson 过期监听
// 监听特定键过期事件
RMapCache<String, String> map = redisson.getMapCache("sessions");
map.addListener(new ExpiredListener<String, String>() {@Overridepublic void onExpired(EntryEvent<String, String> event) {log.info("Session expired: {}", event.getKey());// 触发清理动作}
});
2. RedisJSON 过期扩展
// 使用 RedisJSON 模块设置字段级过期
JSONObject product = new JSONObject();
product.put("id", 1001);
product.put("name", "Laptop");
product.put("price", 999.99);// 设置整体过期
jedis.jsonSetWithEscape("product:1001", product, 3600);// 设置字段级过期(需要RedisJSON 2.6+)
jedis.sendCommand(Command.JSON_SET, "product:1001", ".price", "\"899.99\"", "EX", "600" // 价格字段10分钟后过期
);

总结:Java 开发者必备技能

  1. 策略选择

    • 会话数据 → volatile-ttl
    • 高频访问数据 → volatile-lru
    • 全局数据 → allkeys-lru
  2. 性能口诀

    “小Key高频用惰删,大Key过期启异步;
    动态TTL防雪崩,双删机制保一致”

  3. 监控指标

    指标健康阈值报警条件
    expired_keys/sec<1000持续>5000
    evicted_keys/sec0任何驱逐发生
    mem_fragmentation_ratio1.0-1.5>1.8 或 <0.9

掌握这些知识,你将在 Java 项目中构建高效可靠的 Redis 缓存系统,轻松应对高并发场景下的数据过期挑战。



拓展(Redis内存淘汰策略列举)

Redis 提供了几种内存淘汰策略来处理当可用内存不足时如何自动删除键以释放空间的问题。以下是 Redis 中常见的几种内存淘汰策略:

noeviction 默认的

这是默认的策略。当内存使用达到上限并且客户端尝试执行会导致更多内存使用的命令(比如添加新数据)时,Redis 会返回错误。

实现方式:Redis 直接拒绝执行可能导致内存增加的命令。

例子:假设 Redis 已经达到内存上限,此时执行SET命令添加新的键值对,Redis 会返回错误并拒绝该操作。

volatile-lru

从设置了过期时间的键值对中,移除最近最少使用的键值对。

实现方式:Redis 会维护一个记录设置了过期时间的键的访问时间的队列,当需要淘汰数据时,从队列尾部移除元素。

例子:有多个设置了过期时间的键key1、key2和key3,其中key1最近访问最少,当内存不足时,key1会被淘汰。

volatile-ttl

移除即将过期的键值对,也就是剩余生存时间(TTL)最短的键值对。

实现方式:Redis 会遍历设置了过期时间的键,比较它们的 TTL,选择 TTL 最小的进行淘汰。

例子:键keyA的 TTL 为 10 秒,键keyB的 TTL 为 5 秒,当内存不足时,keyB会被优先淘汰。

volatile-random

在设置了过期时间的键值对中,随机移除某个键值对。

实现方式:通过随机算法从设置了过期时间的键集合中选择一个进行淘汰。

例子:在一组设置了过期时间的键中,随机选取一个如keyX进行淘汰。

allkeys-lru

从所有键值对中,移除最近最少使用的键值对。

实现方式:Redis 维护一个所有键的访问时间队列,淘汰时从队列尾部移除。

例子:包括设置了过期时间和未设置过期时间的多个键,如keyC最近访问最少,当内存不足时,keyC被淘汰。

allkeys-random

从所有键值对中,随机移除某个键值对。

实现方式:通过随机算法从所有键集合中选择一个进行淘汰。

例子:在所有键中,随机选择如keyY进行淘汰。

该拓展部分参考文章:https://cloud.tencent.com/developer/news/1677151


📜文末寄语

  • 🟠关注我,获取更多内容。
  • 🟡技术动态、实战教程、问题解决方案等内容持续更新中。
  • 🟢《全栈知识库》技术交流和分享社区,集结全栈各领域开发者,期待你的加入。
  • 🔵​加入开发者的《专属社群》,分享交流,技术之路不再孤独,一起变强。
  • 🟣点击下方名片获取更多内容🍭🍭🍭👇

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

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

相关文章

Flutter - 原生交互 - 相机Camera - 01

环境 Flutter 3.29 macOS Sequoia 15.4.1 Xcode 16.3 集成 Flutter提供了camera插件来拍照和录视频&#xff0c;它提供了一系列可用的相机&#xff0c;并使用特定的相机展示相机预览、拍照、录视频。 添加依赖 camera: 提供使用设备相机模块的工具path_provider: 寻找存储图…

基于 Amazon Q Developer CLI 和 Amazon Bedrock Knowledge Bases 实现智能问答系统

1. 引言 传统企业通常将常见问题&#xff08;FAQ&#xff09;发布在网站上&#xff0c;方便客户自助查找信息。然而&#xff0c;随着生成式 AI 技术的迅速发展与商业渗透&#xff0c;这些企业正积极探索构建智能问答系统的新途径。这类系统不仅能显著提升客户体验&#xff0c;…

Go 为何天生适合云原生?

当前我们正处在 AI 时代&#xff0c;但是在基础架构领域&#xff0c;仍然处在云原生时代。云原生仍然是当前时代的风口之一。作为一个 Go 开发者&#xff0c;职业进阶的下一站就是学习云原生技术。作为 Go 开发者学习云原生技术有得天独厚的优势&#xff0c;这是因为 Go 天生适…

Mac查看MySQL版本的命令

通过 Homebrew 查看&#xff08;如果是用 Homebrew 安装的&#xff09; brew info mysql 会显示你安装的版本、路径等信息。 你的终端输出显示&#xff1a;你并没有安装 MySQL&#xff0c;只是查询了 brew 中的 MySQL 安装信息。我们一起来看下重点&#xff1a; &#x1f9fe…

Kafka ACK机制详解:数据可靠性与性能的权衡之道

在分布式消息系统中&#xff0c;消息确认机制是保障数据可靠性的关键。Apache Kafka 通过 ACK&#xff08;Acknowledgment&#xff09;机制 实现了灵活的数据确认策略&#xff0c;允许用户在 数据可靠性 和 系统性能 之间进行权衡。本文将深入解析 Kafka ACK 机制的工作原理、配…

FastMCP:构建 MCP 服务器和客户端的高效 Python 框架

在人工智能领域&#xff0c;模型上下文协议&#xff08;Model Context Protocol&#xff0c;简称 MCP&#xff09;作为一种标准化的协议&#xff0c;为大型语言模型&#xff08;LLM&#xff09;提供了丰富的上下文和工具支持。而 FastMCP 作为构建 MCP 服务器和客户端的 Python…

动态库导出符号与extern “C“

1. windows下动态库导出符号 根据C/C语法规则&#xff0c;函数声明中的修饰符&#xff08;如__declspec(dllexport)&#xff09;可以放在返回类型之前或返回类型之后、函数名之前。这两种方式在功能上是等价的&#xff0c;编译器会以相同的方式处理。 __declspec(dllexport) …

Linux(9)——进程(控制篇——下)

目录 三、进程等待 1&#xff09;进程等待的必要性 2&#xff09;获取子进程的status 3&#xff09;进程的等待方法 wait方法 waitpid方法 多进程创建以及等待的代码模型 非阻塞的轮训检测 四、进程程序替换 1&#xff09;替换原理 2&#xff09;替换函数 3&…

Datatable和实体集合互转

1.使用已废弃的 JavaScriptSerializer&#xff0c;且反序列化为弱类型 ArrayList。可用但不推荐。 using System; using System.Collections; using System.Collections.Generic; using System.Data; using System.Linq; using System.Reflection; using System.Web; using Sy…

阿里云服务器ECS详解:云服务器是什么,云服务器优势和应用场景及参考

云服务器ECS是阿里云众多云产品中&#xff0c;最受用户关注的产品&#xff0c;阿里云服务器提供多样化的计算能力&#xff0c;支持x86、Arm架构&#xff0c;涵盖CPU、GPU等多种服务器类型&#xff0c;满足各种用户需求。其便捷易用特性包括分钟级交付、通用API和性能监控框架&a…

【Oracle】游标

个人主页&#xff1a;Guiat 归属专栏&#xff1a;Oracle 文章目录 1. 游标基础概述1.1 游标的概念与作用1.2 游标的生命周期1.3 游标的分类 2. 显式游标2.1 显式游标的基本语法2.1.1 声明游标2.1.2 带参数的游标 2.2 游标的基本操作2.2.1 完整的游标操作示例 2.3 游标属性2.3.1…

pikachu靶场通关笔记11 XSS关卡07-XSS之关键字过滤绕过(三种方法渗透)

目录 一、源码分析 1、进入靶场 2、代码审计 3、攻击思路 二、渗透实战 1、探测过滤信息 2、注入Payload1 3、注入Payload2 4、注入Payload3 本系列为通过《pikachu靶场通关笔记》的XSS关卡(共10关&#xff09;渗透集合&#xff0c;通过对XSS关卡源码的代码审计找到安…

XML 元素:基础、应用与优化

XML 元素:基础、应用与优化 引言 XML(可扩展标记语言)作为一种数据交换的标准格式,广泛应用于互联网数据交换、数据存储等领域。XML 元素是 XML 文档的核心组成部分,本文将深入探讨 XML 元素的概念、特性、应用以及优化方法。 一、XML 元素概述 1.1 XML 元素的定义 X…

【Axure高保真原型】交通事故大屏可视化分析案例

今天和大家分享交通事故大屏可视化分析案例的原型模板&#xff0c;包括饼图分类分析、动态显示发生数、柱状图趋势分析、中部地图展示最新事故发现地点和其他信息、右侧列表记录发生事故的信息…… 通过多种可视化图表展示分析结果&#xff0c;具体效果可以点击下方视频观看或…

HCIP(BGP基础)

一、BGP 基础概念 1. 网络分类与协议定位 IGP&#xff08;内部网关协议&#xff09;&#xff1a;用于自治系统&#xff08;AS&#xff09;内部路由&#xff0c;如 RIP、OSPF、EIGRP&#xff0c;关注选路效率、收敛速度和资源占用。EGP&#xff08;外部网关协议&#xff09;&a…

【HarmonyOS 5】 ArkUI-X开发中的常见问题及解决方案

一、跨平台编译与适配问题 1. 平台特定API不兼容 ‌问题现象‌&#xff1a;使用Router模块的replaceUrl或startAbility等鸿蒙专属API时&#xff0c;编译跨平台工程报错cant support crossplatform application。 ‌解决方案‌&#xff1a; 改用ohos.router的跨平台封装API&a…

Matlab2018a---安装教程

目录 壹 | 引 言 贰 | 安装环境 叁 | 安 装 肆 | 结 语 壹 | 引 言 大家好&#xff0c;我是子正。 最近想学习一下DSP数字信号处理有关的知识&#xff0c;要用到Matlab进行数据处理&#xff0c;于是又重新把Matlab捡了回来; 记得上学那会儿用的还是Matlab2012a&#xff…

分布式流处理与消息传递——Kafka ISR(In-Sync Replicas)算法深度解析

Java Kafka ISR&#xff08;In-Sync Replicas&#xff09;算法深度解析 一、ISR核心原理 #mermaid-svg-OQtnaUGNQ9PMgbW0 {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-OQtnaUGNQ9PMgbW0 .error-icon{fill:#55222…

ARM GIC V3概述

中断类型 locality- specific peripheral interrupt&#xff08;LPI&#xff09;&#xff1a;LPI是一个有针对性的外设中断&#xff0c;通过affinity路由到特定的PE。 为非安全group1中断边沿触发可以通过its进行路由没有active状态&#xff0c;所以不需要明确的停用操作LPI总…

蓝桥杯国赛训练 day1

目录 k倍区间 舞狮 交换瓶子 k倍区间 取模后算组合数就行 import java.util.HashMap; import java.util.Map; import java.util.Scanner;public class Main {static Scanner sc new Scanner(System.in);public static void main(String[] args) {solve();}public static vo…