欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

詳細聊聊Redis的過期策略

 更新時間:2022年01月05日 10:59:39   作者:牛逼程序員  
redis 過期策略是定期刪除+惰性刪除,下面這篇文章主要給大家介紹了關(guān)于Redis過期策略的相關(guān)資料,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下

保存過期時間

Redis可以為每個key設(shè)置過期時間,會將每個設(shè)置了過期時間的key放入一個獨立的字典中。

typedef struct redisDb { 
int id; //id是數(shù)據(jù)庫序號,為0-15(默認Redis有16個數(shù)據(jù)庫) 
long avg_ttl; //存儲的數(shù)據(jù)庫對象的平均ttl(time to live),用于統(tǒng)計 
dict *dict; //存儲數(shù)據(jù)庫所有的key-value 
dict *expires; //存儲key的過期時間 
dict *blocking_keys;//blpop 存儲阻塞key和客戶端對象 
dict *ready_keys;//阻塞后push 響應(yīng)阻塞客戶端 存儲阻塞后push的key和客戶端對象 dict *watched_keys;//存儲watch監(jiān)控的的key和客戶端對象 
} redisDb;

dict 用來維護一個 Redis 數(shù)據(jù)庫中包含的所有 Key-Value 鍵值對,expires則用于維護一個 Redis 數(shù)據(jù)庫中設(shè)置了失效時間的鍵(即key與失效時間的映射)。注意這里的失效時間是用毫秒的時間戳表示的,比如2022-01-02 22:45:02過期則value為1641134702000

當(dāng)我們使用expire命令設(shè)置一個key的失效時間時,Redis 首先到 dict 這個字典表中查找要設(shè)置的key是否存在,如果存在就將這個key和失效時間添加到 expires 這個字典表。

當(dāng)我們使用setex命令向系統(tǒng)插入數(shù)據(jù)時,Redis 首先將 Key 和 Value 添加到 dict 這個字典表中,然后將 Key 和失效時間添加到 expires 這個字典表中。注意setex只能用于字符串。

簡單地總結(jié)來說就是,設(shè)置了失效時間的key和具體的失效時間全部都維護在 expires 這個字典表中。

設(shè)置過期時間

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有四個不同的命令可以用于設(shè)置鍵的生存時間(鍵可以生存多久)或過期時間(鍵什么時候會被刪除):

expire 命令用于將鍵key的生存時間設(shè)置為ttl

pexpire 命令用于將鍵key的生存時間設(shè)置為ttl毫秒

expireat 命令用于將鍵key的過期時間設(shè)置為timestamp所指定的數(shù)時間戳

pexpireat 命令用于將鍵key的過期時間設(shè)置為timestamp所指定的毫秒數(shù)時間戳

注意expire、pexpire、expireat最終實現(xiàn)都是通過pexpireat實現(xiàn)的,也就是說無論客戶端執(zhí)行哪個命令,都會Redis都會轉(zhuǎn)換成pexpireat命令執(zhí)行。所以expires字典中存的時間是用毫秒時間戳表示的鍵的過期時間。

過期策略

如果一個鍵過期了,那什么時候被刪除呢?

有三種過期策略

  • 定時刪除:在設(shè)置鍵的過期時間的同時,創(chuàng)建一個定時器,讓定時器在鍵的過期時間來臨時,立即執(zhí)行對鍵的刪除操作。(創(chuàng)建定時器刪除
  • 惰性刪除:放任鍵的過期不管,但是每次從鍵空間中獲取鍵時,都檢查取得的鍵是否過期,如果過期的話,就刪除該鍵;如果沒有過期,就返回該鍵。(使用的時候刪除
  • 定期刪除:每隔一段時間,程序就對數(shù)據(jù)庫進行一次檢查,刪除里面過期的鍵。至于要刪除多少過期鍵,以及要檢查多少個數(shù)據(jù)庫,則有算法決定。(定期掃描刪除

定時刪除

  • 優(yōu)點

1、對內(nèi)存最友好:通過使用定時器,可以保證過期的鍵會盡可能快地被刪除,釋放所占內(nèi)存

  • 缺點

1、對cpu最不友好:在過期鍵比較多的情況下,刪除過期鍵這一行為可能會占用相當(dāng)一部分cpu的時間,對服務(wù)器的響應(yīng)時間和吞吐量造成影響。

惰性刪除

  • 優(yōu)點

1、對cpu最友好:只有在取出鍵的時候才會對過期鍵進行檢查,即不需要cpu定期掃描,也不需要創(chuàng)建大量的定時器。

  • 缺點

1、對內(nèi)存最不友好:如果一個鍵已經(jīng)過期,但是后面不會被訪問到的話,那么就一直保留在數(shù)據(jù)庫中。如果這樣的鍵過多,無疑會占用很大的內(nèi)存。

定期刪除

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

  • 優(yōu)點

1、定期刪除每隔一段時間執(zhí)行一次過期鍵操作,并通過限制刪除操作執(zhí)行的時長和頻率來減少刪除操作對cpu時間的影響。

2、通過刪除過期鍵,能有效的減少因為過期鍵而帶來的內(nèi)存浪費

  • 缺點 難以確定刪除操作執(zhí)行的時長和頻率

1、如果刪除操作執(zhí)行得太頻繁,或者執(zhí)行的時間太長,定期刪除策略就會退化成定時刪除,以至于占用太多cpu的執(zhí)行時間。

2、如果刪除操作執(zhí)行的時間太少,或執(zhí)行時間太短,定期刪除策略又會和惰性刪除一樣,出現(xiàn)內(nèi)存浪費。

Redis的過期策略

Redis使用是惰性刪除定期刪除兩種策略:通過配好使用這兩種策略,服務(wù)器可以很好地在合理使用cpu時間和避免浪費內(nèi)存空間之間取得平衡。

惰性刪除策略的實現(xiàn)

過期鍵的惰性刪除刪除策略由db.c/expireIfNeeded函數(shù)實現(xiàn),所有讀寫數(shù)據(jù)庫的Redis命令在執(zhí)行之前都會調(diào)用expireIfNeed函數(shù)對輸入鍵進行檢查:

  • 如果鍵已經(jīng)過期,那么expireIfNeeded函數(shù)將鍵刪除
  • 如果鍵未過期,那么expireIfNeeded函數(shù)不做操作

命令調(diào)用expireIfNeeded函數(shù)過程如下圖

image.png

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

image.png

定期刪除策略的實現(xiàn)

過期鍵的定期刪除策略由redis.c/activeExpireCycle函數(shù)實現(xiàn),每當(dāng)Redis的服務(wù)器周期性操作redis.c/serverCron函數(shù)執(zhí)行時,activeExpireCycle函數(shù)就會被調(diào)用,它在規(guī)定時間內(nèi),分多次遍歷服務(wù)器中各個數(shù)據(jù)庫。

Redis 默認每秒進行 10 次過期掃描,過期掃描不會遍歷過期字典中所有的 key, 而是采用了一種簡單的貪心策略,步驟如下。

(1)從過期字典中隨機選出 20個 key。

(2)刪除這 20 個 key 中已經(jīng)過期的 key。

(3)如果過期的 key的比例超過 1/4,那就重復(fù)步驟 (1)。 同時,為了保證過期掃描不會出現(xiàn)循環(huán)過度,導(dǎo)致結(jié)程卡死的現(xiàn)象,算法還增加了掃描時間的上限,默認不會超過 25ms。

假設(shè)一個大型的 Redis 實例中所有的 key 在同一時間過期了,會出現(xiàn)怎樣的結(jié)果呢?

消耗cpu

Redis 會持續(xù)掃描過期字典(循環(huán)多次),直到過期字典中過期的key變得稀疏,才會停止(循環(huán)次數(shù)明顯下降)。

導(dǎo)致請求卡頓或超時

當(dāng)客戶端請求到來時,服務(wù)器如果正好進入過期掃描狀態(tài),客戶端的請求將會等待至少 25ms 后才會進行處理,如果客戶端將超時時間設(shè)置得比較短,比如 10ms,那么就會出現(xiàn)大量的連接因為超時而關(guān)閉 ,業(yè)務(wù)端就會出現(xiàn)很多異常

所以一定要注意過期時間,如果有大批量的key過期,要給過期時間設(shè)置一個隨機范圍,而不能全部在同一時間過期。

參考:

《Redis的設(shè)計與實現(xiàn)》

《Redis深度歷險》

總結(jié)

到此這篇關(guān)于Redis過期策略的文章就介紹到這了,更多相關(guān)Redis過期策略內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 詳解Spring?Boot?訪問Redis的三種方式

    詳解Spring?Boot?訪問Redis的三種方式

    這篇文章主要介紹了Spring?Boot?訪問Redis的三種方式,本文通過示例代碼給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-12-12
  • redis++的編譯?安裝?使用方案

    redis++的編譯?安裝?使用方案

    這篇文章主要介紹了redis++的編譯?安裝?使用方案的相關(guān)資料,需要的朋友可以參考下
    2023-03-03
  • 為啥懶 Redis 是更好的 Redis

    為啥懶 Redis 是更好的 Redis

    本文是由zicode, 李中凱, 無若翻譯的英文文章Lazy Redis is better Redis,小編認為非常不錯,這里推薦給大家
    2018-07-07
  • React?組件的常用生命周期函數(shù)匯總

    React?組件的常用生命周期函數(shù)匯總

    這篇文章主要介紹了React?組件的常用生命周期函數(shù)匯總,組件的生命周期有助于理解組件的運行方式、完成更復(fù)雜的組件功能、分析組件錯誤原因等
    2022-08-08
  • redis如何后臺啟動的方法

    redis如何后臺啟動的方法

    這篇文章主要介紹了redis如何后臺啟動的方法,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-03-03
  • redis實現(xiàn)加鎖的幾種方法示例詳解

    redis實現(xiàn)加鎖的幾種方法示例詳解

    這篇文章主要給大家介紹了關(guān)于redis實現(xiàn)加鎖的幾種方法,加鎖命令分別是INCR、SETNX和SET,文中給出了詳細的示例代碼,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。
    2017-09-09
  • redis-cli 使用密碼登錄的實例

    redis-cli 使用密碼登錄的實例

    今天小編就為大家分享一篇redis-cli 使用密碼登錄的實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-05-05
  • redis如何更新升級版本

    redis如何更新升級版本

    這篇文章主要介紹了redis如何更新升級版本問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-01-01
  • redis中隊列消息實現(xiàn)應(yīng)用解耦的方法

    redis中隊列消息實現(xiàn)應(yīng)用解耦的方法

    這篇文章主要給大家介紹了關(guān)于redis中隊列消息實現(xiàn)應(yīng)用解耦的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2018-09-09
  • 華為歐拉openEuler編譯安裝Redis的實現(xiàn)步驟

    華為歐拉openEuler編譯安裝Redis的實現(xiàn)步驟

    本文主要介紹了華為歐拉openEuler編譯安裝Redis的實現(xiàn)步驟,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-01-01

最新評論