集中過(guò)期
有時(shí)你會(huì)發(fā)現(xiàn)滚停,平時(shí)在使用Redis時(shí)沒(méi)有延時(shí)比較大的情況,但在某個(gè)時(shí)間點(diǎn)突然出現(xiàn)一波延時(shí)粥惧,而且報(bào)慢的時(shí)間點(diǎn)很有規(guī)律键畴,例如某個(gè)整點(diǎn),或者間隔多久就會(huì)發(fā)生一次影晓。
如果出現(xiàn)這種情況镰吵,就需要考慮是否存在大量key集中過(guò)期的情況檩禾。
如果有大量的key在某個(gè)固定時(shí)間點(diǎn)集中過(guò)期挂签,在這個(gè)時(shí)間點(diǎn)訪問(wèn)Redis時(shí),就有可能導(dǎo)致延遲增加盼产。
Redis的過(guò)期策略采用主動(dòng)過(guò)期+懶惰過(guò)期兩種策略:
- 主動(dòng)過(guò)期:Redis內(nèi)部維護(hù)一個(gè)定時(shí)任務(wù)饵婆,默認(rèn)每隔100毫秒會(huì)從過(guò)期字典中隨機(jī)取出20個(gè)key,刪除過(guò)期的key戏售,如果過(guò)期key的比例超過(guò)了25%侨核,則繼續(xù)獲取20個(gè)key,刪除過(guò)期的key灌灾,循環(huán)往復(fù)搓译,直到過(guò)期key的比例下降到25%或者這次任務(wù)的執(zhí)行耗時(shí)超過(guò)了25毫秒,才會(huì)退出循環(huán)
- 懶惰過(guò)期:只有當(dāng)訪問(wèn)某個(gè)key時(shí)锋喜,才判斷這個(gè)key是否已過(guò)期些己,如果已經(jīng)過(guò)期,則從實(shí)例中刪除
注意嘿般,Redis的主動(dòng)過(guò)期的定時(shí)任務(wù)段标,也是在Redis主線程中執(zhí)行的 ,也就是說(shuō)如果在執(zhí)行主動(dòng)過(guò)期的過(guò)程中炉奴,出現(xiàn)了需要大量刪除過(guò)期key的情況逼庞,那么在業(yè)務(wù)訪問(wèn)時(shí),必須等這個(gè)過(guò)期任務(wù)執(zhí)行結(jié)束瞻赶,才可以處理業(yè)務(wù)請(qǐng)求赛糟。此時(shí)就會(huì)出現(xiàn),業(yè)務(wù)訪問(wèn)延時(shí)增大的問(wèn)題砸逊,最大延遲為25毫秒璧南。
而且這個(gè)訪問(wèn)延遲的情況,不會(huì)記錄在慢日志里痹兜。慢日志中只記錄真正執(zhí)行某個(gè)命令的耗時(shí)穆咐,Redis主動(dòng)過(guò)期策略執(zhí)行在操作命令之前,如果操作命令耗時(shí)達(dá)不到慢日志閾值,它是不會(huì)計(jì)算在慢日志統(tǒng)計(jì)中的对湃,但我們的業(yè)務(wù)卻感到了延遲增大崖叫。
此時(shí)你需要檢查你的業(yè)務(wù),是否真的存在集中過(guò)期的代碼拍柒,一般集中過(guò)期使用的命令是expireat或pexpireat命令心傀,在代碼中搜索這個(gè)關(guān)鍵字就可以了。
如果你的業(yè)務(wù)確實(shí)需要集中過(guò)期掉某些key拆讯,又不想導(dǎo)致Redis發(fā)生抖動(dòng)脂男,有什么優(yōu)化方案?
解決方案是种呐,在集中過(guò)期時(shí)增加一個(gè)隨機(jī)時(shí)間宰翅,把這些需要過(guò)期的key的時(shí)間打散即可。
偽代碼可以這么寫:
# 在過(guò)期時(shí)間點(diǎn)之后的5分鐘內(nèi)隨機(jī)過(guò)期掉
redis.expireat(key, expire_time + random(300))
這樣Redis在處理過(guò)期時(shí)爽室,不會(huì)因?yàn)榧袆h除key導(dǎo)致壓力過(guò)大汁讼,阻塞主線程。
另外阔墩,除了業(yè)務(wù)使用需要注意此問(wèn)題之外嘿架,還可以通過(guò)運(yùn)維手段來(lái)及時(shí)發(fā)現(xiàn)這種情況。
做法是我們需要把Redis的各項(xiàng)運(yùn)行數(shù)據(jù)監(jiān)控起來(lái)啸箫,執(zhí)行info可以拿到所有的運(yùn)行數(shù)據(jù)耸彪,在這里我們需要重點(diǎn)關(guān)注expired_keys這一項(xiàng),它代表整個(gè)實(shí)例到目前為止忘苛,累計(jì)刪除過(guò)期key的數(shù)量蝉娜。
我們需要對(duì)這個(gè)指標(biāo)監(jiān)控,當(dāng)在很短時(shí)間內(nèi)這個(gè)指標(biāo)出現(xiàn)突增時(shí)柑土,需要及時(shí)報(bào)警出來(lái)蜀肘,然后與業(yè)務(wù)報(bào)慢的時(shí)間點(diǎn)對(duì)比分析,確認(rèn)時(shí)間是否一致稽屏,如果一致扮宠,則可以認(rèn)為確實(shí)是因?yàn)檫@個(gè)原因?qū)е碌难舆t增大。