* See issue #1525 on Github for more information. */
now = server.lua_caller ? server.lua_time_start : mstime();
/* If we are running in the context of a slave, 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. */
/*如果我們正在slaves上執行讀寫命令,就直接返回,
*因為slaves上的過期是由master來發送刪除命令同步給slaves刪除的,
*slaves不會自主刪除*/
if (server.masterhost != NULL) return now > when;
/*只是回了一個判斷鍵是否過期的值,0表示沒有過期,1表示過期
*但是並沒有做其他與鍵值過期相關的操作*/
/* Return when this key has not expired */
/*如果沒有過期,就返回當前鍵*/
if (now <= when) return 0;
/* Delete the key */
/*增加過期鍵個數*/
server.stat_expiredkeys++;
/*傳播鍵過期的消息*/
propagateExpire(db,key);
notifyKeyspaceEvent(REDIS_NOTIFY_EXPIRED,"expired",key,db->id);
/*刪除過期鍵*/
return dbDelete(db,key);
}
以上是expireIfNeeded函數的源碼,源碼中的註釋已經很清楚的描述出了它的邏輯,我只是將他翻譯成中文,然後加了一點自己的註釋。值得注意的如果是slaves,它是不能自主刪除鍵的,需要由master發del命令,然後同步到所有的slaves,這樣就不會造成主從數據不一致的問題。
(4)策略總述:
懶惰淘汰機制和定時淘汰機制是一起合作的,就好像你開一家餐館一樣,定時淘汰機制就是你每隔幾小時去查看所有的菜品是否還有,如果有的菜品現在賣光了,就將他從菜單上劃掉。懶惰淘汰機制就是有客人要點宮保雞丁,你馬上去查看還有沒有,如果今天的已經賣完了,就告訴客人不好意思,我們賣完了,然後將宮保雞丁從菜單上劃掉。只有等下次有原料再做的時候,才又把它放到菜單上去。
所以,在實際中,如果我們要自己設計過期策略,在使用懶漢式刪除+定期刪除時,控制時長和頻率這個尤為關鍵,需要結合服務器性能,已經併發量等情況進行調整,以致最佳。
三、對開發需求而言,Redis過期策略的設計實現經驗
(1)分析緩存鍵值的客戶方角度,調和服務器內存壓力
基於服務器內存是有限的,但是緩存是必須的,所以我們就要結合起來選擇一個平衡點。所以一般來說,我們採取高訪問量緩存策略—就是給那些經常被訪問的數據,維持它較長的key生存週期。
(2)估算過期時間
這個就要結合我們自己的業務去估量了。
參考因素:數據的訪問量、併發量,數據的變化更新的時間,服務器數據內存大小……
(3)Java演示一策略做法。
每次訪問刷新對應key生存時間:
針對經常訪問的數據的策略
//加進redis時,設置生存時間
@Override
public String set(String key, String value) {
Jedis jedis = jedisPool.getResource();
String string = jedis.set(key, value);
jedis.expire(key,5);
System.out.println("key : "+key);
System.out.println("查看key的剩餘生存時間:"+jedis.ttl(key));
jedis.close();
return string;
}
//從redis獲取時
@Override
public String get(String key) {
Jedis jedis = jedisPool.getResource();
String string = jedis.get(key);
jedis.expire(key,5);//每次訪問刷新時間
jedis.close();
return string;
}
講到這就結束了,大家有什麼不同的見解或意見可以給我留言噢,歡迎大家評論!
閱讀更多 互聯網Java架構 的文章