本文例子基於:5.0.4redis
Redis對於設置了過時時間的key的過時策略有兩種數據庫
惰性刪除的時機在於當你要獲取該key的時候再去作判斷.這裏我以String類型做爲演示畫圖: 服務器
int expireIfNeeded(redisDb *db, robj *key) {
if (!keyIsExpired(db,key)) return 0;
/* If we are running in the context of a slave, instead of * evicting the expired key from the database, we return ASAP: * the slave key expiration is controlled by the master that will * send us synthesized DEL operations for expired keys. * * Still we try to return the right information to the caller, * that is, 0 if we think the key should be still valid, 1 if * we think the key is expired at this time. */
if (server.masterhost != NULL) return 1;
/* Delete the key */
server.stat_expiredkeys++;
propagateExpire(db,key,server.lazyfree_lazy_expire);
notifyKeyspaceEvent(NOTIFY_EXPIRED,
"expired",key,db->id);
return server.lazyfree_lazy_expire ? dbAsyncDelete(db,key) :
dbSyncDelete(db,key);
}
複製代碼
咱們發現,當key有設置了過時時間,而後key已通過期的話,那麼redis會判斷是否開啓了lazyfree_lazy_expire
,若是開啓的話,那麼異步刪除.沒有則同步直接刪除.(4.0以後的特性,當大key刪除的時候很是有用)dom
當有了惰性刪除以後,知足了一部分的需求,但是在實際應用中,會存在有過時而沒有被訪問到的key,這樣就會平白的佔據着內存.那麼redis是經過怎樣去解決的呢?異步
redis會有一個定時任務,每秒跑10次。性能
因爲redis是單線程,若是任由上面定時隨機刪除策略的話,那麼當有大量的key過時的時候,redis會存在沒法處理客戶端請求的狀況?不不不,其實redis在作定時隨機刪除的時候,有一個限制,就是設置掃描時間的上限,默認至多爲25ms(timelimit = 1000000*ACTIVE_EXPIRE_CYCLE_SLOW_TIME_PERC/server.hz/100;),因此當客戶端請求到來時,服務器正處於過時掃描期間,客戶端會等到至多25ms而後進行其業務處理.this
那麼若是redis設置超時時間太短的話,有可能出現大量超時鏈接,爲了不這個問題,建議是在設置過時時間是時候,加多一個隨機範圍,避免大量的key同時過時~spa
當有作主從的時候,從庫是不會開啓定時隨機刪除的,都是依賴master開啓的aof文件中增長一條del命令,而後從庫去執行該語句實現刪除該過時key線程
咱們知道redis是純內存數據庫,若是redis使用超出了內存限制的時候,便會產生swap行爲. 使用磁盤來操做相比內存來講,性能降低的不是一丁半點。 這時候咱們須要設置redis最大使用內存code
maxmemory <bytes>
複製代碼
經過設置maxmemory,當使用內存超過maxmemory的時候,redis提供了幾種可選的策略來控制內存的使用量
端午三天就這樣過去啦~願各位看官好好休息,而後繼續起來搬磚~hhhhh