面試題之redis的緩存失效策略和主鍵失效機制

作為緩存系統都要定期清理無效數據,就需要一個主鍵失效和淘汰策略.

在Redis當中,有生存期的key被稱為volatile。在創建緩存時,要為給定的key設置生存期,當key過期的時候(生存期為0),它可能會被刪除。

1、影響生存時間的一些操作

生存時間可以通過使用 DEL 命令來刪除整個 key 來移除,或者被 SET 和 GETSET 命令覆蓋原來的數據,也就是說,修改key對應的value和使用另外相同的key和value來覆蓋以後,當前數據的生存時間不同。

比如說,對一個 key 執行INCR命令,對一個列表進行LPUSH命令,或者對一個哈希表執行HSET命令,這類操作都不會修改 key 本身的生存時間。另一方面,如果使用RENAME對一個 key 進行改名,那麼改名後的 key的生存時間和改名前一樣。

RENAME命令的另一種可能是,嘗試將一個帶生存時間的 key 改名成另一個帶生存時間的 another_key ,這時舊的 another_key (以及它的生存時間)會被刪除,然後舊的 key 會改名為 another_key ,因此,新的 another_key 的生存時間也和原本的 key 一樣。使用PERSIST命令可以在不刪除 key 的情況下,移除 key 的生存時間,讓 key 重新成為一個persistent key 。

2、如何更新生存時間

可以對一個已經帶有生存時間的 key 執行EXPIRE命令,新指定的生存時間會取代舊的生存時間。過期時間的精度已經被控制在1ms之內,主鍵失效的時間複雜度是O(1),

EXPIRE和TTL命令搭配使用,TTL可以查看key的當前生存時間。設置成功返回 1;當 key 不存在或者不能為 key 設置生存時間時,返回 0 。

最大緩存配置

在 redis 中,允許用戶設置最大使用內存大小

server.maxmemory

默認為0,沒有指定最大緩存,如果有新的數據添加,超過最大內存,則會使redis崩潰,所以一定要設置。redis 內存數據集大小上升到一定大小的時候,就會實行數據淘汰策略。

redis 提供 6種數據淘汰策略:

. volatile-lru:從已設置過期時間的數據集(server.db[i].expires)中挑選最近最少使用的數據淘汰

. volatile-ttl:從已設置過期時間的數據集(server.db[i].expires)中挑選將要過期的數據淘汰

. volatile-random:從已設置過期時間的數據集(server.db[i].expires)中任意選擇數據淘汰

. allkeys-lru:從數據集(server.db[i].dict)中挑選最近最少使用的數據淘汰

. allkeys-random:從數據集(server.db[i].dict)中任意選擇數據淘汰

. no-enviction(驅逐):禁止驅逐數據

注意這裡的6種機制,volatile和allkeys規定了是對已設置過期時間的數據集淘汰數據還是從全部數據集淘汰數據,後面的lru、ttl以及random是三種不同的淘汰策略,再加上一種no-enviction永不回收的策略。

使用策略規則:

1、如果數據呈現冪律分佈,也就是一部分數據訪問頻率高,一部分數據訪問頻率低,則使用allkeys-lru

2、如果數據呈現平等分佈,也就是所有的數據訪問頻率都相同,則使用allkeys-random

三種數據淘汰策略:

ttl和random比較容易理解,實現也會比較簡單。主要是Lru最近最少使用淘汰策略,設計上會對key 按失效時間排序,然後取最先失效的key進行淘汰


分享到:


相關文章: