天天看點

究竟先操作緩存,還是資料庫?

緩存存儲,也是資料的備援。

(1)資料庫通路資料,磁盤IO,慢;

(2)緩存裡通路資料,存操作,快;

(3)資料庫裡的熱資料,可在緩存備援一份;

(4)先通路緩存,如果命中,能大大的提升通路速度,降低資料庫壓力;

這些,是緩存的核心讀加速原理。

但是,一旦沒有命中緩存,或者一旦涉及寫操作,流程會比沒有緩存更加複雜,這些是今天要分享的話題。

讀操作,如果沒有命中緩存,流程是怎麼樣的?

答:如下圖所示

究竟先操作緩存,還是資料庫?

(1)嘗試從緩存get資料,結果沒有命中;

(2)從資料庫擷取資料,讀從庫,讀寫分離;

(3)把資料set到緩存,未來能夠命中緩存;

讀操作的流程應該沒有歧義。

寫操作,流程是怎麼樣的?

答:寫操作,既要操作資料庫中的資料,又要操作緩存裡的資料。

這裡,有兩個方案:

(1)先操作資料庫,再操作緩存;

(2)先操作緩存,再操作資料庫;

并且,希望保證兩個操作的原子性,要麼同時成功,要麼同時失敗。

這演變為一個分布式事務的問題,保證原子性十分困難,很有可能出現一半成功,一半失敗,接下來看下,當原子性被破壞的時候,分别會發生什麼。

一、先操作資料庫,再操作緩存

究竟先操作緩存,還是資料庫?

如上圖,正常情況下:

(1)先操作資料庫,成功;

(2)再操作緩存(delete或者set),也成功;

但如果這兩個動作原子性被破壞:第一步成功,第二步失敗,會導緻,資料庫裡是新資料,而緩存裡是舊資料,業務無法接受。

畫外音:如果第一步就失敗,可以傳回調用方50X,不會出現資料不一緻。

二、先操作緩存,再操作資料庫

究竟先操作緩存,還是資料庫?

(1)先操作緩存(delete或者set),成功;

(2)再操作資料庫,也成功;

畫外音:如果第一步就失敗,也可以傳回調用方50X,不會出現資料不一緻。

如果原子性被破壞,會發生什麼呢?

這裡又分了兩種情況:

(1)操作緩存使用set

(2)操作緩存使用delete

使用set的情況:第一步成功,第二步失敗,會導緻,緩存裡是set後的資料,資料庫裡是之前的資料,資料不一緻,業務無法接受。

并且,一般來說,資料最終以資料庫為準,寫緩存成功,其實并不算成功。

使用delete的情況:第一步成功,第二步失敗,會導緻,緩存裡沒有資料,資料庫裡是之前的資料,資料沒有不一緻,對業務無影響。隻是下一次讀取,會多一次cache miss。

畫外音:此時可以傳回調用方50X。

**最終,先操作緩存,還是先操作資料庫?

**

答:

(1)讀請求,先讀緩存,如果沒有命中,讀資料庫,再set回緩存

(2)寫請求

(2.1)先緩存,再資料庫

(2.2)緩存,使用delete,而不是set
           

畫外音:《緩存,究竟是淘汰,還是修改?》也提到了,淘汰緩存還是修改緩存的建議。

希望大家有收獲,有不同方案歡迎讨論。

末了,挖個坑:

究竟先操作緩存,還是資料庫?

在緩存讀取流程中,如果主從沒有同步完成,步驟二讀取到一個舊資料,可能導緻緩存裡set一個舊資料,最終導緻資料庫和緩存資料不一緻。

如何解決這種情況下,緩存與資料庫資料不一緻的問題,是下一章要讨論的内容。