天天看點

穿透類緩存Cache使用,這一篇就夠了!

有些成熟的技術方案,用不着創新,固化下來的模式(pattern),學就完了。例如,穿透類緩存的使用,“Cache Aside Pattern”就是很好的實踐沉澱,故今天聊一聊Cache Aside Pattern。

畫外音:就好像“設計模式”,它就是沉澱下來的設計方法。

什麼是“Cache Aside Pattern”?

旁路緩存方案的經驗實踐,這個實踐又分讀實踐,寫實踐。

畫外音:與旁路緩存對應的,是穿透緩存。

讀實踐是怎麼樣的?

對于讀請求:

(1)先讀cache,再讀db;

(2)如果,cache hit,則直接傳回資料;

(3)如果,cache miss,則通路db,并将資料set回緩存;

穿透類緩存Cache使用,這一篇就夠了!

如上圖:

(1)先從cache中嘗試get資料,結果miss了;

(2)再從db中讀取資料,從庫,讀寫分離;

(3)最後把資料set回cache,友善下次讀命中;

寫實踐是怎麼樣的?

對于寫請求:

(1)淘汰緩存,而不是更新緩存;

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

穿透類緩存Cache使用,這一篇就夠了!

如上圖:

(1)第一步要操作資料庫,第二步操作緩存;

(2)緩存,采用delete淘汰,而不是set更新;

Cache Aside Pattern為什麼建議淘汰緩存,而不是更新緩存?

如果更新緩存,在并發寫時,可能出現資料不一緻。

穿透類緩存Cache使用,這一篇就夠了!

如上圖所示,如果采用set緩存。

在1和2兩個并發寫發生時,由于無法保證時序,此時不管先操作緩存還是先操作資料庫,都可能出現:

(1)請求1先操作資料庫,請求2後操作資料庫;

(2)請求2先set了緩存,請求1後set了緩存;

導緻,資料庫與緩存之間的資料不一緻。

是以,Cache Aside Pattern建議,delete緩存,而不是set緩存。

Cache Aside Pattern為什麼建議先操作資料庫,再操作緩存?

如果先操作緩存,在讀寫并發時,可能出現資料不一緻。

穿透類緩存Cache使用,這一篇就夠了!

如上圖所示,如果先操作緩存。

在1和2并發讀寫發生時,由于無法保證時序,可能出現:

(1)寫請求淘汰了緩存;

(2)寫請求操作了資料庫(主從同步沒有完成);

(3)讀請求讀了緩存(cache miss);

(4)讀請求讀了從庫(讀了一個舊資料);

(5)讀請求set回緩存(set了一個舊資料);

(6)資料庫主從同步完成;

導緻,資料庫與緩存的資料不一緻。

是以,Cache Aside Pattern建議,先操作資料庫,再操作緩存。

Cache Aside Pattern方案存在什麼問題?

答:如果先操作資料庫,再淘汰緩存,在原子性被破壞時:

(1)修改資料庫成功了;

(2)淘汰緩存失敗了;

導緻,資料庫與緩存的資料不一緻。

Cache Aside Pattern總結:

對于讀請求:

(1)先讀cache,再讀db;

(2)如果,cache hit,則直接傳回資料;

(3)如果,cache miss,則通路db,并将資料set回緩存;

對于寫請求:

(1)淘汰緩存,而不是更新緩存;

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

任何技術方案的設計,都是折衷。