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
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/83563.shtml
英文地址,請注明出處:http://en.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…