1. 程式人生 > >25、如何保證快取與資料庫雙寫時的資料一致性?

25、如何保證快取與資料庫雙寫時的資料一致性?

1、面試題

如何保證快取與資料庫的雙寫一致性?

2、面試官心裡分析

你只要用快取,就可能會涉及到快取與資料庫雙儲存雙寫,你只要是雙寫,就一定會有資料一致性的問題,那麼你如何解決一致性問題?

3、面試題剖析

一般來說,就是如果你的系統不是嚴格要求快取+資料庫必須一致性的話,快取可以稍微的跟資料庫偶爾有不一致的情況,最好不要做這個方案,讀請求和寫請求序列化,串到一個記憶體佇列裡去,這樣就可以保證一定不會出現不一致的情況。

序列化之後,就會導致系統的吞吐量會大幅度的降低,用比正常情況下多幾倍的機器去支撐線上的一個請求。

一、Cache Aside Pattern快取+資料庫讀寫模式的分析

最經典的快取+資料庫讀寫的模式,cache aside pattern

1、Cache Aside Pattern

(1)讀的時候,先讀快取,快取沒有的話,那麼就讀資料庫,然後取出資料後放入快取,同時返回響應;

(2)更新的時候,先刪除快取,然後再更新資料庫。

cache aside pattern.png

2、為什麼是刪除快取,而不是更新快取呢?

原因很簡單,很多時候,複雜點的快取的場景,因為快取有的時候,不簡單是資料庫中直接取出來的值;

商品詳情頁的系統,修改庫存,只是修改了某個表的某些欄位,但是要真正把這個影響的最終的庫存計算出來,可能還需要從其他表查詢一些資料,然後進行一些複雜的運算,才能最終計算出;

現在最新的庫存是多少,然後才能將庫存更新到快取中去;

比如可能更新了某個表的一個欄位,然後其對應的快取,是需要查詢另外兩個表的資料,並進行運算,才能計算出快取最新的值的;

更新快取的代價是很高的;

是不是說,每次修改資料庫的時候,都一定要將其對應的快取去跟新一份?也許有的場景是這樣的,但是對於比較複雜的快取資料計算的場景,就不是這樣了;

如果你頻繁修改一個快取涉及的多個表,那麼這個快取會被頻繁的更新,頻繁的更新快取;

但是問題在於,這個快取到底會不會被頻繁訪問到?

舉個例子,一個快取涉及的表的欄位,在1分鐘內就修改了20次,或者是100次,那麼快取跟新20次,100次; 但是這個快取在1分鐘內就被讀取了1次,有大量的冷資料,

28法則,黃金法則,20%的資料,佔用了80%的訪問量,

實際上,如果你只是刪除快取的話,那麼1分鐘內,這個快取不過就重新計算一次而已,開銷大幅度降低,

每次資料過來,就只是刪除快取,然後修改資料庫,如果這個快取,在1分鐘內只是被訪問了1次,那麼只有那1次,快取是要被重新計算的,用快取才去算快取,

其實刪除快取,而不是更新快取,就是一個lazy計算的思想,不要每次都重新做複雜的計算,不管它會不會用到,而是讓它到需要被使用的時候再重新計算,

mybatis,hibernate,懶載入,思想

查詢一個部門,部門帶了一個員工的list,沒有必要說每次查詢部門,都裡面的1000個員工的資料也同時查出來啊

80%的情況,查這個部門,就只是要訪問這個部門的資訊就可以了,

先查部門,同時要訪問裡面的員工,那麼這個時候只有在你要訪問裡面的員工的時候,才會去資料庫裡面查詢1000個員工。

文集:https://www.jianshu.com/nb/32293473