如何制定Redis過期策略

* 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;

}

講到這就結束了,大家有什麼不同的見解或意見可以給我留言噢,歡迎大家評論!


分享到:


相關文章: