一文聊聊Redis中的過期策略
這篇文章帶大家介紹一下Redis中的過期策略,看看惰性刪除策略、定期刪除策略的實作方法,希望對大家有幫助!
儲存過期時間
#Redis可以設定每個key過期時間,會將每個設定了過期時間的key放入一個獨立的字典。 【相關推薦:Redis影片教學】
typedef struct redisDb { int id; //id是数据库序号,为0-15(默认Redis有16个数据库) long avg_ttl; //存储的数据库对象的平均ttl(time to live),用于统计 dict *dict; //存储数据库所有的key-value dict *expires; //存储key的过期时间 dict *blocking_keys;//blpop 存储阻塞key和客户端对象 dict *ready_keys;//阻塞后push 响应阻塞客户端 存储阻塞后push的key和客户端对象 dict *watched_keys;//存储watch监控的的key和客户端对象 } redisDb;
dict 用來維護一個Redis 資料庫中包含的所有Key-Value 鍵值對,expires則用來維護一個Redis 資料庫中設定了失效時間的鍵(即key與失效時間的映射)。 注意這裡的失效時間是用毫秒的時間戳表示的,例如2022-01-02 22:45:02過期則value為1641134702000
當我們使用expire指令設定一個key的失效時間時,Redis 首先到dict 這個字典表中尋找要設定的key是否存在,如果存在就將這個key和失效時間加到expires 這個字典表。
當我們使用setex指令向系統插入資料時,Redis 首先將 Key 和 Value 加入 dict 這個字典表中,然後將 Key 和失效時間加入 expires 這個字典表中。 注意setex只能用於字串。
簡單地總結來說就是,設定了失效時間的key和具體的失效時間全部都維護在 expires 這個字典表中。
設定過期時間
expire的使用
expire指令的使用方法如下: expire key ttl(單位秒)
127.0.0.1:6379> expire name 2 #2秒失效 (integer) 1 127.0.0.1:6379> get name (nil) 127.0.0.1:6379> set name zhangfei OK 127.0.0.1:6379> ttl name #永久有效 (integer) -1 127.0.0.1:6379> expire name 30 #30秒失效 (integer) 1 127.0.0.1:6379> ttl name #还有24秒失效 (integer) 24 127.0.0.1:6379> ttl name #失效 (integer) -2
Redis有四個不同的指令可以用來設定鍵的生存時間(鍵可以生存多久)或過期時間(鍵什麼時候會被刪除):
expire 指令用於將鍵key的生存時間設定為ttl秒
pexpire 指令用於將鍵key的生存時間設定為ttl毫秒
expireat 指令用於將鍵key的過期時間設定為timestamp所指定的秒數時間戳
#pexpireat 指令用於將鍵key的過期時間設定為timestamp所指定的毫秒數時間戳
注意expire、pexpire、expireat最終實作都是透過pexpireat實現的,也就是說無論客戶端執行哪個指令,都會將Redis轉換成pexpireat指令執行。所以expires字典中存的時間是用毫秒時間戳表示的鍵的過期時間。
過期策略
如果一個鍵過期了,那什麼時候被刪除呢?
有三種過期策略
- 定時刪除:在設定鍵的過期時間的同時,建立一個定時器,讓定時器在鍵的過期時間來臨時,立即執行對鍵的刪除操作。 (建立定時器刪除)
- 惰性刪除:放任鍵的過期不管,但是每次從鍵空間中取得鍵時,都檢查取得的鍵是否過期,如果過期的話,就刪除該鍵;如果沒有過期,就返回該鍵。 (使用的時候刪除)
- 定期刪除:每隔一段時間,程式就會對資料庫進行一次檢查,刪除裡面過期的鍵。至於要刪除多少過期鍵,以及要檢查多少個資料庫,則有演算法決定。 (定期掃描刪除)
#定時刪除
- 優點
1、對記憶體最友善:透過使用定時器,可以保證過期的鍵會盡可能快地被刪除,釋放所佔記憶體
- 缺點
惰性刪除
- 優點
- 缺點
定期刪除
定期刪除是上面的定時刪除和惰性刪除的一中折中方案。- 優點
- 缺點難以確定刪除操作執行的時長和頻率
Redis的過期策略
Redis使用是惰性刪除和定期刪除兩種策略:透過配好使用這兩種策略,伺服器可以很好地在合理使用cpu時間和避免浪費記憶體空間之間取得平衡。
惰性刪除策略的實現
過期鍵的惰性刪除刪除策略由db.c/expireIfNeeded函數實現,所有讀寫資料庫的Redis命令在執行之前都會呼叫expireIfNeed函數對輸入鍵進行檢查:
- 如果鍵已經過期,那麼expireIfNeeded函數將鍵刪除
- 如果鍵未過期,那麼expireIfNeeded函數不做操作
指令呼叫expireIfNeeded函數程序如下圖
#另外因為每個被存取的鍵都可能被刪除,所以每個指令都必須能同時處理鍵存在以及不存在的情況。 下圖表示get指令的執行過程
有定期刪除策略的實作
##過期鍵的定期刪除策略由redis.c/activeExpireCycle函數實現,每當Redis的伺服器週期性操作redis.c/serverCron函數執行時,activeExpireCycle函數就會被調用,它在規定時間內,分多次遍歷伺服器中各個資料庫。 Redis 預設每秒進行 10 次過期掃描,過期掃描不會遍歷過期字典中所有的 key, 而是採用了一種簡單的貪心策略,步驟如下。 (1)從過期字典中隨機選出 20個 key。 (2)刪除這 20 個 key 中已經過期的 key。 (3)如果過期的 key的比例超過 1/4,那就重複步驟 (1)。同時,為了確保過期掃描不會出現循環過度,導致結程卡死的現象,演算法也增加了掃描時間的上限,預設不會超過 25ms。 假設一個大型的Redis 實例中所有的key 在同一時間過期了,會出現怎樣的結果呢?消耗cpu
Redis會持續掃描過期字典(循環多次),直到過期字典中過期的key變得稀疏,才會停止(循環次數明顯下降)。導致請求卡頓或逾時
當客戶端請求到來時,伺服器如果剛好進入過期掃描狀態,客戶端的請求將會等待至少25ms 後才會進行處理,如果客戶端將超時時間設定得比較短,例如10ms,那麼就會出現大量的連線因為超時而關閉,業務端就會出現很多異常##所以一定要注意過期時間,如果有大批量的key過期,要給過期時間設定一個隨機範圍,而不能全部在同一時間過期。更多程式相關知識,請造訪:
程式設計入門以上是一文聊聊Redis中的過期策略的詳細內容。更多資訊請關注PHP中文網其他相關文章!

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

Redis集群模式通過分片將Redis實例部署到多個服務器,提高可擴展性和可用性。搭建步驟如下:創建奇數個Redis實例,端口不同;創建3個sentinel實例,監控Redis實例並進行故障轉移;配置sentinel配置文件,添加監控Redis實例信息和故障轉移設置;配置Redis實例配置文件,啟用集群模式並指定集群信息文件路徑;創建nodes.conf文件,包含各Redis實例的信息;啟動集群,執行create命令創建集群並指定副本數量;登錄集群執行CLUSTER INFO命令驗證集群狀態;使

如何清空 Redis 數據:使用 FLUSHALL 命令清除所有鍵值。使用 FLUSHDB 命令清除當前選定數據庫的鍵值。使用 SELECT 切換數據庫,再使用 FLUSHDB 清除多個數據庫。使用 DEL 命令刪除特定鍵。使用 redis-cli 工具清空數據。

要從 Redis 讀取隊列,需要獲取隊列名稱、使用 LPOP 命令讀取元素,並處理空隊列。具體步驟如下:獲取隊列名稱:以 "queue:" 前綴命名,如 "queue:my-queue"。使用 LPOP 命令:從隊列頭部彈出元素並返回其值,如 LPOP queue:my-queue。處理空隊列:如果隊列為空,LPOP 返回 nil,可先檢查隊列是否存在再讀取元素。

使用 Redis 指令需要以下步驟:打開 Redis 客戶端。輸入指令(動詞 鍵 值)。提供所需參數(因指令而異)。按 Enter 執行指令。 Redis 返迴響應,指示操作結果(通常為 OK 或 -ERR)。

在CentOS系統上,您可以通過修改Redis配置文件或使用Redis命令來限制Lua腳本的執行時間,從而防止惡意腳本佔用過多資源。方法一:修改Redis配置文件定位Redis配置文件:Redis配置文件通常位於/etc/redis/redis.conf。編輯配置文件:使用文本編輯器(例如vi或nano)打開配置文件:sudovi/etc/redis/redis.conf設置Lua腳本執行時間限制:在配置文件中添加或修改以下行,設置Lua腳本的最大執行時間(單位:毫秒)

使用Redis進行鎖操作需要通過SETNX命令獲取鎖,然後使用EXPIRE命令設置過期時間。具體步驟為:(1) 使用SETNX命令嘗試設置一個鍵值對;(2) 使用EXPIRE命令為鎖設置過期時間;(3) 當不再需要鎖時,使用DEL命令刪除該鎖。

使用 Redis 命令行工具 (redis-cli) 可通過以下步驟管理和操作 Redis:連接到服務器,指定地址和端口。使用命令名稱和參數向服務器發送命令。使用 HELP 命令查看特定命令的幫助信息。使用 QUIT 命令退出命令行工具。

Redis數據過期策略有兩種:定期刪除:定期掃描刪除過期鍵,可通過 expired-time-cap-remove-count、expired-time-cap-remove-delay 參數設置。惰性刪除:僅在讀取或寫入鍵時檢查刪除過期鍵,可通過 lazyfree-lazy-eviction、lazyfree-lazy-expire、lazyfree-lazy-user-del 參數設置。
