Redis 內存淘汰策略深度解析

Redis 作為高性能的內存數據庫,其內存資源的高效管理直接關系到系統的穩定性和性能。當 Redis 的內存使用達到配置的最大值(maxmemory)時,新的寫入操作將觸發內存淘汰機制(Eviction Policy),以釋放空間存儲新數據。本文將深入探討 Redis 的內存淘汰策略、實現原理、適用場景及最佳實踐。

一、 內存淘汰策略概述

Redis 的內存淘汰策略決定了在內存不足時,如何選擇需要刪除的鍵來釋放空間。這些策略可以分為兩大類:

  • ?基于過期時間的淘汰?(volatile-*):僅針對設置了過期時間的鍵。
  • 全局淘汰?(allkeys-*):針對所有鍵,無論是否設置過期時間。

Redis 支持以下 8 種內存淘汰策略

?noeviction:默認策略,禁止寫入新數據,直接返回錯誤。
?volatile-lru:淘汰最近最少使用(LRU)的設置了過期時間的鍵。
?volatile-lfu:淘汰最不經常使用(LFU)的設置了過期時間的鍵。
?volatile-random:隨機淘汰設置了過期時間的鍵。
?volatile-ttl:優先淘汰剩余生存時間(TTL)最短的鍵。
?allkeys-lru:淘汰所有鍵中最近最少使用的鍵。
?allkeys-lfu:淘汰所有鍵中最不經常使用的鍵。
?allkeys-random:隨機淘汰任意鍵。

二、內存淘汰策略詳解

2.1 ?noeviction(不淘汰)?

?行為:當內存不足時,拒絕所有寫入命令(如 SET、LPUSH),但允許讀取操作。
?適用場景:適用于數據不可丟失的場景(如持久化存儲),需確保內存足夠或配合持久化機制。
?缺點:若內存不足且無持久化,可能導致服務不可用。

2.2 ?LRU(Least Recently Used)?

?原理:淘汰最近最久未被訪問的鍵。
?Redis 實現:Redis 使用近似 LRU 算法,通過隨機采樣(默認取 5 個鍵)選擇最久未使用的鍵,而非遍歷所有鍵,以減少計算開銷。
?適用場景:適用于緩存場景,優先保留熱點數據。
?命令示例

CONFIG SET maxmemory-policy volatile-lru  # 針對帶過期時間的鍵
CONFIG SET maxmemory-policy allkeys-lru   # 針對所有鍵

2.3 ?LFU(Least Frequently Used)?

?原理:淘汰訪問頻率最低的鍵(Redis 4.0 引入)。
?Redis 實現:通過計數器統計鍵的訪問頻率,并隨時間衰減歷史計數,避免長期累積導致無法淘汰舊鍵。
?適用場景:適合長期緩存,如高頻訪問的靜態數據。
?命令示例

CONFIG SET maxmemory-policy volatile-lfu  # 針對帶過期時間的鍵
CONFIG SET maxmemory-policy allkeys-lfu   # 針對所有鍵

2.4 ?TTL(Time To Live)?

?原理:優先淘汰剩余生存時間(TTL)最短的鍵。
?適用場景:適用于明確知道鍵生命周期的場景(如臨時會話數據)。
?限制:僅對設置了過期時間的鍵生效。
?命令示例

CONFIG SET maxmemory-policy volatile-ttl

2.5 ?Random(隨機淘汰)?

?原理:隨機選擇鍵進行淘汰。
?適用場景:內存壓力大且數據重要性均等時,快速釋放內存。
?命令示例

CONFIG SET maxmemory-policy volatile-random  # 針對帶過期時間的鍵
CONFIG SET maxmemory-policy allkeys-random   # 針對所有鍵

三、 內存淘汰的底層實現

3.1 ?LRU/LFU 的近似算法

  • Redis 通過 ?evictionPoolEntry?結構維護候選淘汰鍵池。每次淘汰時,隨機采樣一組鍵,更新其訪問時間或頻率信息,選擇最不活躍的鍵刪除。
  • ?LRU 時鐘:Redis 使用全局 24 位時鐘(精度為秒)記錄鍵的最近訪問時間。內存中每個對象存儲與全局時鐘的差值(lru字段),而非精確時間戳。
  • ?LFU 計數器:每個鍵的 lru 字段被拆分為兩部分:
    • 高 16 位:最近訪問時間的分鐘級精度。
    • 低 8 位:訪問頻率計數器(0~255),通過概率遞增,隨時間衰減。

3.2 ?淘汰流程

  1. 客戶端執行寫入命令觸發內存檢查。
  2. Redis 檢查 maxmemory 是否已超出。
  3. 根據配置的策略選擇待淘汰鍵。
  4. 刪除鍵并觸發相關事件(如 evicted 通知)。

四、 如何選擇合適的內存淘汰策略?

4.1 ?緩存場景

?推薦策略:allkeys-lru 或 allkeys-lfu
?理由:優先保留熱點數據,最大化緩存命中率。

4.2 ?持久化存儲

?推薦策略:noeviction(需確保內存足夠或啟用持久化)。
?替代方案:若允許部分數據丟失,可使用 volatile-lru 結合過期時間。

4.3 ?臨時數據場景

?推薦策略:volatile-ttl
?理由:自動清理生命周期明確的數據(如驗證碼、會話信息)。

4.4 ?混合型數據

?推薦策略:allkeys-lru + 部分鍵設置過期時間。
?示例:電商系統中,商品詳情用 allkeys-lru 緩存,購物車數據設置 TTL。

五、最佳實踐與注意事項

5.1 ?配置建議

?設置合理的 maxmemory:通常為物理內存的 80%~90%,避免 OOM。
?監控內存使用:

INFO memory  # 查看內存指標(used_memory、maxmemory)
INFO stats    # 查看 evicted_keys(淘汰鍵數量)

5.2 ?避免大規模淘汰

?分片設計:通過集群分散數據,減少單個節點的內存壓力。
?預熱緩存:重啟后預加載高頻數據,避免冷啟動時集中淘汰。

5.3 ?常見誤區

?volatile-ttl 不依賴惰性刪除:該策略僅在內存不足時觸發,仍需依賴定期/惰性刪除清理過期鍵。
?LFU 計數器并非精確值:訪問頻率通過概率遞增,適用于相對比較而非絕對計數。

六、總結

Redis 的內存淘汰策略是平衡內存使用與性能的關鍵機制。理解不同策略的原理和適用場景,結合業務需求合理配置,可顯著提升系統的穩定性和效率。在高并發場景下,建議通過監控工具(如 RedisInsight、Prometheus)實時跟蹤內存和淘汰指標,動態調整策略和資源配置。

通過本文的深度解析,希望您能掌握 Redis 內存淘汰的核心機制,并在實踐中靈活運用,構建高效可靠的 Redis 服務。

參考資料

Redis 官方文檔:https://redis.io/docs/reference/eviction/
《Redis 設計與實現》——黃健宏
Redis 源碼解析(evict.c、object.c)

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/72953.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/72953.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/72953.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【面試】Java 集合

集合 1、常見的集合有哪些2、說說 List、Set、Queue、Map 四者的區別3、Collection 和 Collections 有什么區別4、Comparable 和 Comparator 的區別5、ArrayList 和 LinkedList 的區別是什么6、ArrayList 和 Vector 的區別是什么7、ArrayList 和 Vector 的擴容機制8、CopyOnWri…

【c++】平移字符串

說明 實現字符串的左移與右移 示例代碼 #include <iostream> #include <string> using namespace std;int main() {string str1 "12345";//左移2位string str2 str1.substr(2) str1.substr(0, 2);cout << str2 << endl;//右移2位&…

密碼學(終極版)

加密 & 解密 備注&#xff1a;密碼學領域不存在完全不能破解的密碼&#xff0c;但是如果一個密碼需要很久很久&#xff0c;例如一萬年才能破解&#xff0c;就認為這個密碼是安全的了。 對稱加密 非對稱加密 公鑰加密、私鑰解密 私鑰簽名、公鑰認證 非對稱的底層原理是…

FreeRTOS任務狀態查詢

一.任務相關API vTaskList&#xff08;&#xff09;&#xff0c;創建一個表格描述每個任務的詳細信息 char biaoge[1000]; //定義一個緩存 vTaskList(biaoge); //將表格存到這緩存中 printf("%s /r/n",biaoge); 1.uxTaskPriorityGet&#xff08;&#xf…

yolov5代碼詳解--3.python代碼腳本

三、val.py val.py的主要作用是對訓練好的模型進行驗證&#xff08;或評估&#xff09;。具體來說&#xff0c;它用于在指定的驗證集上評估模型的性能&#xff0c;計算各項評估指標&#xff0c;并輸出結果。val.py通常在模型訓練完成后運行&#xff0c;用于驗證模型的檢測精度、…

無人機應用探索:玻纖增強復合材料的疲勞性能研究

隨著無人機技術的快速發展&#xff0c;輕量化已成為其結構設計的核心需求。玻纖增強復合材料憑借高強度、低密度和優異的耐環境性能&#xff0c;成為無人機機身、旋翼支架等關鍵部件的理想選擇。然而&#xff0c;無人機在服役過程中需應對復雜多變的環境&#xff1a;高空飛行時…

Python SQLite3 保姆級教程:從零開始學數據庫操作

Python SQLite3 保姆級教程&#xff1a;從零開始學數據庫操作 本文適合純新手&#xff01;無需任何數據庫基礎&#xff0c;跟著步驟操作即可掌握 SQLite3 的核心用法。 目標&#xff1a;讓你像用記事本一樣輕松操作數據庫&#xff01; 目錄 什么是 SQLite3&#xff1f;環境準…

C語言中的整數類型(short,int,long和long long)

整數是編程中最常見的一種數據類型&#xff0c;C語言提供了多種整數類型&#xff0c;包括 short、int、long 和 long long&#xff0c;它們的主要區別在于存儲范圍和內存占用的大小。 本節將詳細講解這些整數類型的定義、特性、使用場景以及注意事項&#xff0c;幫助你全面理解…

使用jcodec庫,訪問網絡視頻提取封面圖片上傳至oss

注釋部分為FFmpeg&#xff08;確實方便但依賴太大&#xff0c;不想用&#xff09; package com.zuodou.upload;import com.aliyun.oss.OSS; import com.aliyun.oss.model.ObjectMetadata; import com.aliyun.oss.model.PutObjectRequest; import com.zuodou.oss.OssProperties;…

游戲引擎學習第147天

倉庫:https://gitee.com/mrxiao_com/2d_game_3 上一集回顧 具體來說&#xff0c;我們通過隱式計算來解決問題&#xff0c;而不是像數字微分分析器那樣逐步增加數據。我們已經涵蓋了這個部分&#xff0c;并計劃繼續處理音量問題。不過&#xff0c;實際上我們現在不需要繼續處理…

使用Dockerfile打包java項目生成鏡像部署到Linux_java項目打docker鏡像的dockerfile

比起容器、鏡像來說&#xff0c;Dockerfile 非常普通&#xff0c;它就是一個純文本&#xff0c;里面記錄了一系列的構建指令&#xff0c;比如選擇基礎鏡像、拷貝文件、運行腳本等等&#xff0c;每個指令都會生成一個 Layer&#xff0c;而 Docker 順序執行這個文件里的所有步驟&…

Linux -- 磁盤結構、文件系統ext2

一、磁盤 1.磁盤的物理結構 2.磁盤的存儲結構 盤片&#xff1a;是機械硬盤存儲數據的主要介質&#xff0c;一般由鋁合金或玻璃等材料制成&#xff0c;表面涂有一層磁性材料。數據通過磁頭在盤片的磁性涂層上進行磁化來記錄&#xff0c;磁化的不同方向代表二進制的 0 和 1。盤面…

標量、向量、矩陣與張量:從維度理解數據結構的層次

在數學和計算機科學中,維度描述了數據結構的復雜性,而標量、向量、矩陣、張量則是不同維度的數據表示形式。它們的關系可以理解為從簡單到復雜的擴展,以下是詳細解析: 1. 標量(Scalar):0維數據 定義:單個數值,沒有方向,只有大小。 維度:0維(無索引)。 示例: 溫度…

點云數據處理--splat轉3dtiles

文章目錄 處理流程簡介核心功能實現數據讀取與格式轉換定義Point類數據讀取splat轉gltf 點云數據分割定義四叉樹遞歸生成3dtiles瓦片 生成tileset.json遞歸生成tileset.json計算box 主函數調用渲染 下一步工作性能優化渲染效果調優其他 源碼地址&#xff1a; github 處理流程簡…

OneM2M:全球性的物聯網標準-可應用于物聯網中

OneM2M 是一個全球性的物聯網(IoT)標準,旨在為物聯網設備和服務提供統一的框架和接口,以實現設備之間的互操作性、數據共享和服務集成。OneM2M 由多個國際標準化組織(如 ETSI、TIA、TTC、ARIB 等)共同制定,目標是解決物聯網領域的碎片化問題,提供一個通用的標準,支持跨…

【Python 入門基礎】—— 人工智能“超級引擎”,AI界的“瑞士軍刀”,

歡迎來到ZyyOvO的博客?&#xff0c;一個關于探索技術的角落&#xff0c;記錄學習的點滴&#x1f4d6;&#xff0c;分享實用的技巧&#x1f6e0;?&#xff0c;偶爾還有一些奇思妙想&#x1f4a1; 本文由ZyyOvO原創??&#xff0c;感謝支持??&#xff01;請尊重原創&#x1…

Java爬蟲獲取淘寶商品詳情數據的完整指南

在電商領域&#xff0c;獲取商品詳情數據對于市場分析、價格監控、用戶體驗優化等場景具有重要意義。淘寶作為國內領先的電商平臺&#xff0c;提供了豐富的API接口供開發者使用&#xff0c;其中item_get和item_get_pro接口可以用來獲取商品的詳細信息。本文將詳細介紹如何使用J…

Ubuntu 下 nginx-1.24.0 源碼分析 - ngx_init_cycle 函數

nei聲明在 src/core/ngx_cycle.h ngx_cycle_t *ngx_init_cycle(ngx_cycle_t *old_cycle);實現在 src/core/ngx_cycle.c ngx_cycle_t * ngx_init_cycle(ngx_cycle_t *old_cycle) {void *rv;char **senv;ngx_uint_t i, n;ngx_log_t …

qt 操作多個sqlite文件

qt 操作多個sqlite文件 Chapter1 qt 操作多個sqlite文件1. 引入必要的頭文件2. 創建并連接多個SQLite數據庫3. 代碼說明4. 注意事項 Chapter2 qt 多線程操作sqlite多文件1. 引入必要的頭文件2. 創建數據庫操作的工作線程類3. 在主線程中創建并啟動多個工作線程4. 代碼說明5. 運…

最新版本WebContext構造函數-避坑

import org.thymeleaf.context.IWebContext; import org.thymeleaf.context.WebContext; 當你想把頁面信息全部獲取出來存到redis緩存中使用時&#xff0c;SpringWebContext在Spring5中報錯 SpringWebContext ctx new SpringWebContext(request, response,request.getServlet…