【58沈劍 架構師之路】緩存,到底是淘汰,仍是修改?

容許cache miss的場景,無論是memcache仍是redis,當被緩存的內容變化時,是修改緩存,仍是淘汰緩存?這是今天將要討論的話題。html

 

問:KV緩存都緩存了一些什麼數據?

(1)樸素類型的數據,例如:int
(2)序列化後的對象,例如:User實體,本質是binary
(3)文本數據,例如:json或者html
(4)...redis

 

問:淘汰緩存中的這些數據,修改緩存中的這些數據,有什麼差異?

(1)淘汰某個key,操做簡單,直接將key置爲無效,但下一次該key的訪問會cache miss
(2)修改某個key的內容,邏輯相對複雜,但下一次該key的訪問仍會cache hitjson

 

能夠看到,差別僅僅在於一次cache miss緩存

 

問:緩存中的value數據通常是怎麼修改的?

(1)樸素類型的數據,直接set修改後的值便可
(2)序列化後的對象:通常須要先get數據,反序列化成對象,修改其中的成員,再序列化爲binary,再set數據
(3)json或者html數據:通常也須要先get文本,parse成doom樹對象,修改相關元素,序列化爲文本,再set數據ui

 

結論:對於對象類型,或者文本類型修改緩存value的成本較高,通常選擇直接淘汰緩存。spa

 

問:對於樸素類型的數據,究竟應該修改緩存,仍是淘汰緩存?
答:仍然視狀況而定。htm

 

案例1對象

假設,緩存裏存了某一個用戶uid=123的餘額是money=100元,業務場景是,購買了一個商品pid=456。get


分析:若是修改緩存,可能須要:
(1)去db查詢pid的價格是50元
(2)去db查詢活動的折扣是8折(商品實際價格是40元)
(3)去db查詢用戶的優惠券是10元(用戶實際要支付30元)
(4)從cache查詢get用戶的餘額是100元
(5)計算出剩餘餘額是100 - 30 = 70
(6)到cache設置set用戶的餘額是70
爲了不一次cache miss,須要額外增長若干次db與cache的交互,得不償失it

 

結論:此時,應該淘汰緩存,而不是修改緩存。

 

案例2

假設,緩存裏存了某一個用戶uid=123的餘額是money=100元,業務場景是,須要扣減30元。

 

分析:若是修改緩存,須要:
(1)從cache查詢get用戶的餘額是100元
(2)計算出剩餘餘額是100 - 30 = 70
(3)到cache設置set用戶的餘額是70
爲了不一次cache miss,須要額外增長若干次cache的交互,以及業務的計算,得不償失


結論:此時,應該淘汰緩存,而不是修改緩存。

 

案例3

假設,緩存裏存了某一個用戶uid=123的餘額是money=100元,業務場景是,餘額要變爲70元。

 

分析:若是修改緩存,須要:
(1)到cache設置set用戶的餘額是70
修改緩存成本很低

 

結論:此時,能夠選擇修改緩存。固然,若是選擇淘汰緩存,只會額外增長一次cache miss,成本也不高。

 

總結
容許cache miss的KV緩存寫場景:

  • 大部分狀況,修改value成本會高於「增長一次cache miss」,所以應該淘汰緩存

  • 若是還在糾結,老是淘汰緩存,問題也不大

相關文章
相關標籤/搜索