網站首頁 編程語言 正文
一、前言
在文章開始之前,我先問大家一個問題:當我們使用指令:expire key second
給一個key設置過期時間,過期時間一到,這個key對應的過期數據
真的被服務器立即刪除了嗎?答案是并不會立即刪除。知道了這個答案,就來看看Redis中如何處理過期的數據。
二、Redis中的數據特征
Redis是一種內存級數據庫,所有數據均存放在內存中,內存中的數據可以通過TTL指令獲取其狀態,有三種狀態:?
指令結果 | 狀態 |
---|---|
XX | 具有時效性的數據 |
-1 | 永久有效的數據 |
-2 | 已經過期的數據?或 被刪除的數據 或 未定義的數據 |
三、時效性數據儲存結構
當我們用指令設置過期數據后,數據對應的地址會放在expires空間中,存儲方式是哈希,存儲的value是過期時間。
四、數據刪除策略
數據刪除策略目標:
在內存占用與CPU占用之間尋找一種平衡,顧此失彼都會造成整體redis性能的下降,甚至引發服務器宕機或內存泄露
1、定時刪除
- 創建一個定時器,當key設置有過期時間,且過期時間到達時,由定時器任務立即執行對鍵的刪除操作
- 優點:節約內存,到時就刪除,快速釋放掉不必要的內存占用
- 缺點:CPU壓力很大,無論CPU此時負載量多高,均占用CPU,會影響redis服務器響應時間和指令吞吐量
2、惰性刪除
- 數據到達過期時間,不做處理。等下次訪問該數據時,會調用
expireIfNeeded()
函數來判斷該數據是否過期: 如果未過期,返回數據,發現已過期,刪除,返回不存在 - 優點:節約CPU性能,發現必須刪除的時候才刪除
- 缺點:內存壓力很大,出現長期占用內存的數據
3、定期刪除
流程分析:
- Redis服務器啟動初始化時,讀取配置server.hz的值,默認為10
- 然后每秒鐘執行10次
serverCron()
方法,該方法用來檢測服務器 -
serverCron()
方法又會調用databasesCron()
方法,該方法是用來遍歷數據庫的,redis默認有16個數據庫,從第一個數據庫開始 -
databasesCron()
方法又會調用activeExpireCycle()
方法,該方法會對每一個expires[*]
逐一進行檢測,每次執行250ms/server.hz;對某個expires[*]
檢測時,隨機挑選W個key檢測 - 如果檢測到key超時,則刪除key;如果一輪中刪除的key的數量>W25%,循環該過程;如果一輪中刪除的key的數量≤W25%,檢查下一個
expires[*]
,0-15循環。其中W取值=ACTIVE_EXPIRE_CYCLE_LOOKUPS_PER_LOOP屬性值 - 如果activeExpireCycle()執行時間到期,下次從current_db繼續向下執行
- 參數current_db用于記錄activeExpireCycle() 進入哪個expires[*] 執行
-
總結:
周期性輪詢redis庫中的時效性數據,采用隨機抽取的策略,利用過期數據占比的方式控制刪除頻度 - 內存壓力不是很大,長期占用內存的冷數據會被持續清理
五、刪除策略對比
定時刪除 | 節約內存,無占用 | 不分時段占用CPU資源,頻度高 | 拿時間換空間 |
---|---|---|---|
惰性刪除 | 內存占用嚴重 | 延時執行,CPU利用率高 | 拿空間換時間 |
定期刪除 | 內存定期隨機清理 | 每秒花費固定的CPU資源維護內存 | 隨機抽查,重點抽查 |
六、逐出算法
1、概念引入
當新數據進入redis時,如果內存不足怎么辦?Redis使用內存存儲數據,在執行每一個命令前,會調用freeMemoryIfNeeded()
檢測內存是否充足。如果內存不滿足新加入數據的最低存儲要求,redis要臨時刪除一些數據為當前指令清理存儲空間。清理數據的策略稱為逐出算法。
注意:逐出數據的過程不是100%能夠清理出足夠的可使用的內存空間,如果不成功則反復執行。當對所有數據嘗試完畢后,如果不能達到內存清理的要求,將出現錯誤信息。
2、八種配置
檢測易失數據(可能會過期的數據集server.db[i].expires
)
volatile-lru | 挑選最近最少使用的數據淘汰 |
---|---|
volatile-lfu | 挑選最近使用次數最少的數據淘汰 |
volatile-ttl | 挑選將要過期的數據淘汰 |
volatile-random | 任意選擇數據淘汰 |
檢測全庫數據(所有數據集server.db[i].dict
)
allkeys-lru | 挑選最近最少使用的數據淘汰 |
---|---|
allkeys-lfu | 挑選最近使用次數最少的數據淘汰 |
allkeys-random | 任意選擇數據淘汰 |
放棄數據驅逐:
no-enviction | 禁止驅逐數據(redis4.0中默認策略) |
---|
原文鏈接:https://cabbage.blog.csdn.net/article/details/125706124
相關推薦
- 2022-08-23 python多線程對多核cpu的利用解析_python
- 2022-08-26 一文搞懂Go語言中文件的讀寫與創建_Golang
- 2023-02-27 C語言中互斥鎖與自旋鎖及原子操作使用淺析_C 語言
- 2022-01-30 VSCode標簽內的代碼塊無法折疊問題解決
- 2022-10-26 Anaconda環境變量的配置圖文詳解_python
- 2022-06-24 jQuery一鍵移除使前端項目脫離對它的依賴_jquery
- 2024-07-15 Spring Boot多環境指定yml或者properties
- 2023-10-15 element-ui里el-progress:進度條問題的解決Invalid prop: custo
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支