Redis的緩存策略和主鍵失效機(jī)制
作為緩存系統(tǒng)都要定期清理無(wú)效數(shù)據(jù)五督,就需要一個(gè)主鍵失效和淘汰策略兴猩。
在Redis當(dāng)中埂陆,有生存期的key被稱為volatile煌张。在創(chuàng)建緩存時(shí)呐赡,要為給定的key設(shè)置生存期,當(dāng)key過(guò)期的時(shí)候(生存期為0)骏融,它可能會(huì)被刪除链嘀。
影響生存時(shí)間的一些操作
生存時(shí)間可以通過(guò)使用 DEL
命令來(lái)刪除整個(gè) key
來(lái)移除,或者被 SET
和 GETSET
命令覆蓋原來(lái)的數(shù)據(jù)档玻,也就是說(shuō)怀泊,修改 key
對(duì)應(yīng)的value和使用另外相同的 key
和 value
來(lái)覆蓋以后,當(dāng)前數(shù)據(jù)的生存時(shí)間不同误趴。
比如說(shuō)霹琼,對(duì)一個(gè) key
執(zhí)行 INCR
命令,對(duì)一個(gè)列表進(jìn)行 LPUSH
命令冤留,或者對(duì)一個(gè)哈希表執(zhí)行HSET命令碧囊,這類操作都不會(huì)修改 key
本身的生存時(shí)間。另一方面纤怒,如果使用RENAME對(duì)一個(gè) key
進(jìn)行改名糯而,那么改名后的 key
的生存時(shí)間和改名前一樣。
RENAME命令的另一種可能是泊窘,嘗試將一個(gè)帶生存時(shí)間的 key
改名成另一個(gè)帶生存時(shí)間的 another_key
熄驼,這時(shí)舊的 another_key
(以及它的生存時(shí)間)會(huì)被刪除,然后舊的 key
會(huì)改名為 another_key
烘豹,因此瓜贾,新的 another_key
的生存時(shí)間也和原本的 key
一樣。使用PERSIST命令可以在不刪除 key
的情況下携悯,移除 key
的生存時(shí)間祭芦,讓 key
重新成為一個(gè) persistent key
。
如何更新生存時(shí)間
可以對(duì)一個(gè)已經(jīng)帶有生存時(shí)間的 key
執(zhí)行 EXPIRE
命令憔鬼,新指定的生存時(shí)間會(huì)取代舊的生存時(shí)間龟劲。過(guò)期時(shí)間的精度已經(jīng)被控制在1ms之內(nèi)胃夏,主鍵失效的時(shí)間復(fù)雜度是O(1),
EXPIRE
和 TTL
命令搭配使用昌跌,TTL
可以查看 key
的當(dāng)前生存時(shí)間仰禀。設(shè)置成功返回 1;當(dāng) key
不存在或者不能為 key
設(shè)置生存時(shí)間時(shí)蚕愤,返回 0 答恶。
最大緩存配置
在 redis 中,允許用戶設(shè)置最大使用內(nèi)存大小
server.maxmemory
默認(rèn)為0萍诱,沒(méi)有指定最大緩存悬嗓,如果有新的數(shù)據(jù)添加,超過(guò)最大內(nèi)存砂沛,則會(huì)使 redis 崩潰烫扼,所以一定要設(shè)置。redis 內(nèi)存數(shù)據(jù)集大小上升到一定大小的時(shí)候碍庵,就會(huì)實(shí)行數(shù)據(jù)淘汰策略。
redis 提供 6種數(shù)據(jù)淘汰策略
volatile-lru:從已設(shè)置過(guò)期時(shí)間的數(shù)據(jù)集(server.db[i].expires)中挑選最近最少使用的數(shù)據(jù)淘汰
volatile-ttl:從已設(shè)置過(guò)期時(shí)間的數(shù)據(jù)集(server.db[i].expires)中挑選將要過(guò)期的數(shù)據(jù)淘汰
volatile-random:從已設(shè)置過(guò)期時(shí)間的數(shù)據(jù)集(server.db[i].expires)中任意選擇數(shù)據(jù)淘汰
allkeys-lru:從數(shù)據(jù)集(server.db[i].dict)中挑選最近最少使用的數(shù)據(jù)淘汰
allkeys-random:從數(shù)據(jù)集(server.db[i].dict)中任意選擇數(shù)據(jù)淘汰
no-enviction(驅(qū)逐):禁止驅(qū)逐數(shù)據(jù)
注意這里的6種機(jī)制悟狱,volatile和allkeys規(guī)定了是對(duì)已設(shè)置過(guò)期時(shí)間的數(shù)據(jù)集淘汰數(shù)據(jù)還是從全部數(shù)據(jù)集淘汰數(shù)據(jù)静浴,后面的lru、ttl以及random是三種不同的淘汰策略挤渐,再加上一種no-enviction永不回收的策略苹享。
使用策略規(guī)則
1、如果數(shù)據(jù)呈現(xiàn)冪律分布浴麻,也就是一部分?jǐn)?shù)據(jù)訪問(wèn)頻率高得问,一部分?jǐn)?shù)據(jù)訪問(wèn)頻率低,則使用allkeys-lru
2软免、如果數(shù)據(jù)呈現(xiàn)平等分布宫纬,也就是所有的數(shù)據(jù)訪問(wèn)頻率都相同,則使用allkeys-random
三種數(shù)據(jù)淘汰策略
ttl
和 random
比較容易理解膏萧,實(shí)現(xiàn)也會(huì)比較簡(jiǎn)單漓骚。主要是Lru最近最少使用淘汰策略,設(shè)計(jì)上會(huì)對(duì) key
按失效時(shí)間排序榛泛,然后取最先失效的 key
進(jìn)行淘汰