機(jī)器的內(nèi)存是有限的,當(dāng)Redis的內(nèi)存超了允許的最大內(nèi)存,Redis會(huì)按照設(shè)定的淘汰策略刪掉超出部分的內(nèi)容。在進(jìn)行淘汰時(shí),先判斷是否設(shè)置了最大允許內(nèi)存(server.maxmemory);若是,會(huì)調(diào)用函數(shù)freeMemoryIfNeeded,再判斷使用內(nèi)存是否超出最大內(nèi)存限制;若是,就按照設(shè)置的淘汰策略淘汰Key,直到使用內(nèi)存小于最大內(nèi)存。

可以設(shè)置不同的淘汰策略決定刪除的方法。Redis默認(rèn)有6種淘汰策略,如上圖所示。前三種都是從已經(jīng)設(shè)置過期時(shí)間的Key中刪除。Key是臨時(shí)數(shù)據(jù),若設(shè)了過期時(shí)間,相比于普通數(shù)據(jù),優(yōu)先級(jí)會(huì)低一些。這里要注意,lru會(huì)影響前面所講的整數(shù)對(duì)象的共享。
淘汰算法
淘汰算法的步驟分為五步:首先,依次遍歷所有db;然后,按照設(shè)置的淘汰策略挑選一個(gè)Key進(jìn)行淘汰;若策略是lru或ttl,采用近似算法,隨機(jī)取n個(gè)樣本(默認(rèn)為5,可配置),從中選出最佳值;遍歷完后,計(jì)算當(dāng)前使用內(nèi)存量是否超過允許值;若是,則繼續(xù)步驟1。
因?yàn)榇蟛糠值牟僮鞫际且訩ey為單位,若一個(gè)容器對(duì)象很大,對(duì)整個(gè)Key操作,或直接刪除Key耗時(shí)過長(zhǎng),從而導(dǎo)致其他命令長(zhǎng)時(shí)間內(nèi)沒法響應(yīng)到。另外,寫入大Key導(dǎo)致內(nèi)存超出太多,下次淘汰就需要淘汰很多內(nèi)存。比如說最大內(nèi)存是1G,寫1G內(nèi)存時(shí)發(fā)現(xiàn)最大內(nèi)存沒有超,但是若再寫入一個(gè)5G的數(shù)據(jù),等下一個(gè)命令來,發(fā)現(xiàn)Redis里面有6G數(shù)據(jù),說明有5G的數(shù)據(jù)要去刪除,那么刪除時(shí),不會(huì)一下就取到5G的數(shù)值,很有可能會(huì)把其他所有的Key都刪除之后,發(fā)現(xiàn)還不夠,然后再刪除那5G的數(shù)據(jù)。還有一個(gè)情況,內(nèi)存100%且無Key可淘汰時(shí),這些命令全都不允許再操作了。
原地址:https://mp.weixin.qq.com/s/n4HXKXPKf87qgZ_e6s4gPg