問:KV緩存都緩存了一些什么數(shù)據(jù)?
答:
(1)樸素類型的數(shù)據(jù),例如:int
(2)序列化后的對象档押,例如:User實(shí)體煌往,本質(zhì)是binary
(3)文本數(shù)據(jù),例如:json或者h(yuǎn)tml
(4)...
問:淘汰緩存中的這些數(shù)據(jù)糠爬,修改緩存中的這些數(shù)據(jù)寇荧,有什么差別?
答:
(1)淘汰某個(gè)key执隧,操作簡單,直接將key置為無效镀琉,但下一次該key的訪問會(huì)cache miss
(2)修改某個(gè)key的內(nèi)容峦嗤,邏輯相對復(fù)雜,但下一次該key的訪問仍會(huì)cache hit
可以看到屋摔,差異僅僅在于一次cache miss钓试。
問:緩存中的value數(shù)據(jù)一般是怎么修改的亚侠?
答:
(1)樸素類型的數(shù)據(jù)硝烂,直接set修改后的值即可
(2)序列化后的對象:一般需要先get數(shù)據(jù)滞谢,反序列化成對象,修改其中的成員狮杨,再序列化為binary母截,再set數(shù)據(jù)
(3)json或者h(yuǎn)tml數(shù)據(jù):一般也需要先get文本,parse成doom樹對象橄教,修改相關(guān)元素清寇,序列化為文本喘漏,再set數(shù)據(jù)
結(jié)論:對于對象類型,或者文本類型华烟,修改緩存value的成本較高翩迈,一般選擇直接淘汰緩存。
問:對于樸素類型的數(shù)據(jù)盔夜,究竟應(yīng)該修改緩存负饲,還是淘汰緩存?
答:仍然視情況而定喂链。
案例1:
假設(shè)返十,緩存里存了某一個(gè)用戶uid=123的余額是money=100元,業(yè)務(wù)場景是椭微,購買了一個(gè)商品pid=456吧慢。
分析:如果修改緩存,可能需要:
(1)去db查詢pid的價(jià)格是50元
(2)去db查詢活動(dòng)的折扣是8折(商品實(shí)際價(jià)格是40元)
(3)去db查詢用戶的優(yōu)惠券是10元(用戶實(shí)際要支付30元)
(4)從cache查詢get用戶的余額是100元
(5)計(jì)算出剩余余額是100 - 30 = 70
(6)到cache設(shè)置set用戶的余額是70
為了避免一次cache miss赏表,需要額外增加若干次db與cache的交互检诗,得不償失。
結(jié)論:此時(shí)瓢剿,應(yīng)該淘汰緩存逢慌,而不是修改緩存。
案例2:
假設(shè)间狂,緩存里存了某一個(gè)用戶uid=123的余額是money=100元攻泼,業(yè)務(wù)場景是,需要扣減30元鉴象。
分析:如果修改緩存忙菠,需要:
(1)從cache查詢get用戶的余額是100元
(2)計(jì)算出剩余余額是100 - 30 = 70
(3)到cache設(shè)置set用戶的余額是70
為了避免一次cache miss,需要額外增加若干次cache的交互纺弊,以及業(yè)務(wù)的計(jì)算牛欢,得不償失。
結(jié)論:此時(shí)淆游,應(yīng)該淘汰緩存傍睹,而不是修改緩存。
案例3:
假設(shè)犹菱,緩存里存了某一個(gè)用戶uid=123的余額是money=100元拾稳,業(yè)務(wù)場景是,余額要變?yōu)?0元腊脱。
分析:如果修改緩存访得,需要:
(1)到cache設(shè)置set用戶的余額是70
修改緩存成本很低。
結(jié)論:此時(shí)陕凹,可以選擇修改緩存悍抑。當(dāng)然鳄炉,如果選擇淘汰緩存,只會(huì)額外增加一次cache miss传趾,成本也不高。
總結(jié):
允許cache miss的KV緩存寫場景:
大部分情況泥技,修改value成本會(huì)高于“增加一次cache miss”浆兰,因此應(yīng)該淘汰緩存
如果還在糾結(jié),總是淘汰緩存珊豹,問題也不大