1. 程式人生 > >緩存,究竟是淘汰,還是修改?

緩存,究竟是淘汰,還是修改?

簡單 設置 余額 問題 red 內容變化 uid htm emca

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

問:KV緩存都緩存了一些什麽數據?
答:
(1)樸素類型的數據,例如:int
(2)序列化後的對象,例如:User實體,本質是binary
(3)文本數據,例如:json或者html
(4)...

問:淘汰緩存中的這些數據,修改緩存中的這些數據,有什麽差別?
答:
(1)淘汰某個key,操作簡單,直接將key置為無效,但下一次該key的訪問會cache miss
(2)修改某個key的內容,邏輯相對復雜,但下一次該key的訪問仍會cache hit

可以看到,差異僅僅在於一次cache miss。

問:緩存中的value數據一般是怎麽修改的?
答:
(1)樸素類型的數據,直接set修改後的值即可
(2)序列化後的對象:一般需要先get數據,反序列化成對象,修改其中的成員,再序列化為binary,再set數據
(3)json或者html數據:一般也需要先get文本,parse成doom樹對象,修改相關元素,序列化為文本,再set數據

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

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

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

分析:如果修改緩存,可能需要:
(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的交互,得不償失。

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

案例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”,因此應該淘汰緩存
如果還在糾結,總是淘汰緩存,問題也不大
作者:58沈劍

緩存,究竟是淘汰,還是修改?