一、什么是一致性問(wèn)題為了提升服務(wù)的性能,我們一般會(huì)把熱點(diǎn)放進(jìn)緩存,那么這些熱點(diǎn)數(shù)據(jù)就同時(shí)存在于數(shù)據(jù)庫(kù)和緩存中,緩存中的數(shù)據(jù)和數(shù)據(jù)庫(kù)中的數(shù)據(jù)要保持一致,這便是緩存一致性問(wèn)題。 二、使用緩存存在的問(wèn)題加了緩存之后,讀寫流程大概如下: 1. 讀流程 2. 寫流程 3. 寫操作的應(yīng)該更新緩存還是刪除緩存 答案是應(yīng)該刪除緩存,如果是更新,可能會(huì)有如下問(wèn)題: 如上圖所示,如果線程 A 先更新了 DB,接著線程 B 更新 DB,正常情況,緩存中保存的應(yīng)該是線程 B 寫入 DB 的數(shù)據(jù),但因?yàn)樽詈笫蔷€程 A 去更新的緩存,因此導(dǎo)致 DB 和緩存中的數(shù)據(jù)不一致。 4. 既然要用刪除,刪除操作在更新DB之前還是之后呢 答案是之前,如果是之后,可能會(huì)出現(xiàn)如下問(wèn)題: 如果先更新 DB,在更新了 DB 之后,還沒(méi)來(lái)得及刪除緩存之前,線程 B 讀請(qǐng)求進(jìn)來(lái)了,那么讀取到的是緩存中的舊數(shù)據(jù),也會(huì)出現(xiàn)一致性問(wèn)題。 5. 先刪除再操作DB就沒(méi)問(wèn)題嗎 答案是也會(huì)有問(wèn)題,可能會(huì)出現(xiàn)如下場(chǎng)景: 線程 A 先刪除了緩存,還沒(méi)來(lái)得及更新 DB 的時(shí)候,線程 B 進(jìn)來(lái)了,把 DB 中的舊數(shù)據(jù)又讀取到了緩存中,最后線程 A 更新了 DB,數(shù)據(jù)還是不一致。 三、緩存一致性問(wèn)題的解決方案1. 雙刪延遲策略 上面說(shuō)了先刪除緩存還是會(huì)存在問(wèn)題,就是線程 A 更新 DB 之前如果線程 B 把數(shù)據(jù)讀到緩存中了,數(shù)據(jù)也會(huì)不一致。雙刪延遲策略就是更新了 DB 后休眠一段時(shí)間再次刪除緩存,如下:
2. 使用binlog異步刪除緩存 我們知道,DB 的操作一般都會(huì)記錄到日志中,比如 MySQL,所有的寫操作都會(huì)記錄到 binlog 中,那么我們可以通過(guò) binlog,去刪除緩存。canal 就是一款用來(lái)解析數(shù)據(jù)庫(kù)日志的工具,我們可以接入 canal,采集到日志,然后通過(guò) MQ 異步的去刪除緩存,這樣對(duì)業(yè)務(wù)代碼就沒(méi)有入侵了。異步刪除緩存流程如下:
|
|