目錄
儲存過期時間
設定過期時間
過期策略
Redis的過期策略
首頁 資料庫 Redis 一文聊聊Redis中的過期策略

一文聊聊Redis中的過期策略

Jan 07, 2022 pm 07:05 PM
redis 過期策略

這篇文章帶大家介紹一下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、對記憶體最友善:透過使用定時器,可以保證過期的鍵會盡可能快地被刪除,釋放所佔記憶體

  • 缺點
##1、對cpu最不友善:在過期鍵比較多的情況下,刪除過期鍵此行為可能會佔用相當一部分cpu的時間,對伺服器的回應時間和吞吐量造成影響。

惰性刪除

    優點
1、對cpu最友善:只有在取出鍵的時候才會對過期鍵進行檢查,即不需要cpu定期掃描,也不需要建立大量的定時器。

    缺點
1、對記憶體最不友善:如果一個鍵已經過期,但是後面不會被存取的話,那麼就一直保留在資料庫中。如果這樣的鍵過多,無疑會佔用很大的記憶體。

定期刪除

定期刪除是上面的定時刪除和惰性刪除的一中折中方案。

    優點
1、定期刪除每隔一段時間執行一次過期鍵操作,並透過限制刪除操作執行的長度和頻率來減少刪除操作對cpu時間的影響。

2、透過刪除過期鍵,能有效的減少因為過期鍵而帶來的記憶體浪費

    缺點難以確定刪除操作執行的時長和頻率
1、如果刪除操作執行得太頻繁,或是執行的時間太長,定期刪除策略就會退化成定時刪除,以至於佔用太多cpu的執行時間。

2、如果刪除操作執行的時間太少,或執行時間太短,定期刪除策略又會和惰性刪除一樣,出現記憶體浪費。

Redis的過期策略

Redis使用是惰性刪除定期刪除兩種策略:透過配好使用這兩種策略,伺服器可以很好地在合理使用cpu時間和避免浪費記憶體空間之間取得平衡。

惰性刪除策略的實現

過期鍵的惰性刪除刪除策略由db.c/expireIfNeeded函數實現,所有讀寫資料庫的Redis命令在執行之前都會呼叫expireIfNeed函數對輸入鍵進行檢查:

  • 如果鍵已經過期,那麼expireIfNeeded函數將鍵刪除
  • 如果鍵未過期,那麼expireIfNeeded函數不做操作

指令呼叫expireIfNeeded函數程序如下圖

一文聊聊Redis中的過期策略

#另外因為每個被存取的鍵都可能被刪除,所以每個指令都必須能同時處理鍵存在以及不存在的情況。 下圖表示get指令的執行過程

一文聊聊Redis中的過期策略

有定期刪除策略的實作

##過期鍵的定期刪除策略由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中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

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

AI Clothes Remover

AI Clothes Remover

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

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

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

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

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

redis集群模式怎麼搭建 redis集群模式怎麼搭建 Apr 10, 2025 pm 10:15 PM

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

redis數據怎麼清空 redis數據怎麼清空 Apr 10, 2025 pm 10:06 PM

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

redis怎麼讀取隊列 redis怎麼讀取隊列 Apr 10, 2025 pm 10:12 PM

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

redis指令怎麼用 redis指令怎麼用 Apr 10, 2025 pm 08:45 PM

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

centos redis如何配置Lua腳本執行時間 centos redis如何配置Lua腳本執行時間 Apr 14, 2025 pm 02:12 PM

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

redis怎麼使用鎖 redis怎麼使用鎖 Apr 10, 2025 pm 08:39 PM

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

redis命令行怎麼用 redis命令行怎麼用 Apr 10, 2025 pm 10:18 PM

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

redis過期策略怎麼設置 redis過期策略怎麼設置 Apr 10, 2025 pm 10:03 PM

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

See all articles