redis過期時間的一大坑

Redis的過期設置,大家基本都用過了。但是裡面的坑不知道各位是否瞭解。

redis過期時間的一大坑

先從基礎講起。

Redis中的所有數據結構都可以設置超時時間,設置超時有四種做法:

EXPIRE 將key的生存時間設置為ttl秒

PEXPIRE 將key的生成時間設置為ttl毫秒

EXPIREAT 將key的過期時間設置為timestamp所代表的的秒數的時間戳

PEXPIREAT 將key的過期時間設置為timestamp所代表的的毫秒數的時間戳

如果讓我們自己來設計過期刪除策略,我們會怎麼做?

redis過期時間的一大坑

可能會想到做一個掃描器,對超時的key進行定時掃描收割。

但是內存中的key太多了,不可能做全部掃描。redis的做法是將設置了超時時間的key放到一個單獨的字典中,以後對這個字典進行單獨掃描。

但是,如果這個字典過大,仍然有全部掃描一次會耗時很長的問題。

這裡redis的做法值得我們借鑑:

Redis採用一種惰性刪除的策略,即過期的key並不會被立即刪除。

Redis默認每秒掃描10次超時字典。每次隨機取出20個key,對這20個key進行超時刪除。如果有超多四分之一(即5個)的key被刪除了.那麼再去取20個key進行超時刪除。一直這樣循環下去,直到字典中過期的ley變得稀疏。

同時,為了保證過期掃描不會出現循環過度,導致線程卡死現象,算法還增加了掃描時間的上限,默認不會超過 25ms。

那麼,這種策略還是有一個問題是,對於一個大型redis,如果客戶端請求到來時,正好在進行過期掃描,並且過期的key非常多,一直掃描了25ms。如果這個客戶端的請求設置了超時時間10ms,那麼就會出現大量的客戶端連接因為超時而關閉。

redis過期時間的一大坑

所以,這就引出了Redis設置超時策略一個坑:

不要將大量的key,設置在同一時間過期。

這種情況下最好加一個指定過期時間上加一個隨機變量時間。


分享到:


相關文章: