分布式之資料庫和快取雙寫一致性方案解析

2021-09-13 18:06:09 字數 1157 閱讀 6977

一.為什麼寫這邊文章

但是,在更新快取方面,對於更新完資料庫,是更新快取呢,還是刪除快取?又或者是先刪除快取,再更新資料庫?其實這一塊是存在很大的爭議。

二、文章結構

講解快取更新策略;

對每種策略進行缺點分析;

針對缺點給出改進方案;

三、正文

先做乙個說明,從理論上來說,給快取設定過期時間,是保證最終一致性的解決方案。這種方案下,我們可以對快取的資料設定過期時間,所有的寫操作以資料庫為準,對快取操作只是盡最大努力即可。也就是說如果資料庫寫成功,快取更新失敗,那麼只要到達過期時間,則後面的讀請求自然會從資料庫中讀取新值,然後回填快取。因此,接下來討論的思路不依賴於給快取設定過期時間這個方案。在這裡,我們討論三種更新策略:

為什麼沒有先更新快取,再更新資料庫這種策略?答案不用說了吧。

四、先更新資料庫,再更新快取

原因一:執行緒安裝角度

同時又請求a和請求b進行更新操作,那麼會出現:

執行緒a更新了資料庫

執行緒b更新了資料庫

執行緒b更新了快取

執行緒a更新了快取

這就出現請求a更新快取應該比請求b更新快取早才對,但是因為網路等原因,b比a更早更新了快取。這就導致了髒資料,因此不考慮!

原因二、業務場景角度

有如下兩點:

1)如果你是乙個寫資料庫場景比較多,而讀資料場景比較少的業務需求,採用這種方案就會導致,資料壓根還沒讀到,快取就被頻繁的更新,浪費效能。

2)如果你寫入資料庫的值,並不是直接寫入快取的,而是要經過一系列負責的計算再寫入快取。那麼,每次寫入資料庫後,都要再次計算寫入快取的值,無疑是浪費效能的。顯然,刪除快取更為合適。

接下來討論的就是爭議最大的,先刪除快取,再更新資料庫。還是先更新資料庫,再刪除快取的問題。

五、先刪除快取,再更新資料庫

該方案會導致不一致的原因:同時有乙個請求a進行更新操作,另乙個請求b進行查詢操作。那麼就會出現以下情形:

上述情況就會導致不一致的請求出現。而且,如果不採用給快取設定過期時間策略,該資料永遠都是髒資料。

那麼,該如何解決呢?採用延時雙刪除策略!偽**如下:

public void write(string key, object data)
解釋一下:

這麼做,可以將1秒內所造成的快取髒資料,再次刪除!

分布式之資料庫和快取雙寫一致性方案解析

對每種策略進行缺點分析 針對缺點給出改進方案 先刪除快取,再更新資料庫 先更新資料庫,再刪除快取 執行緒b更新了資料庫 執行緒b更新了快取 執行緒a更新了快取 請求b查詢發現快取不存在 請求b去資料庫查詢得到舊值 請求b將舊值寫入快取 請求a將新值寫入資料庫 public void write st...

分布式之資料庫和快取雙寫一致性方案解析

為什麼寫這篇文章?首先,快取由於其高併發和高效能的特性,已經在專案中被廣泛使用。在讀取快取方面,大家沒啥疑問,都是按照下圖的流程來進行業務操作。但是在更新快取方面,對於更新完資料庫,是更新快取呢,還是刪除快取。又或者是先刪除快取,再更新資料庫,其實大家存在很大的爭議。目前沒有一篇全面的部落格,對這幾...

分布式之資料庫和快取雙寫一致性方案解析

首先,快取由於其高併發和高效能的特性,已經在專案中被廣泛使用。在讀取快取方面,大家沒啥疑問,都是按照下圖的流程來進行業務操作。但是在更新快取方面,對於更新完資料庫,是更新快取呢,還是刪除快取。又或者是先刪除快取,再更新資料庫,其實大家存在很大的爭議。目前沒有一篇全面的部落格,對這幾種方案進行解析。於...