數據庫緩存一致性問題

緩存是高併發高性能的利器數據庫

可是在使用緩存時,特別是更新緩存和更新數據庫之間的前後順序,不少人有不一樣的爭議。緩存

策略

  • 先更新數據庫,再更新緩存;
  • 先刪除緩存,再更新數據庫;
  • 先更新數據庫,再刪除緩存;

第一種方案安全

存在線程安全問題,同時若是數據更新頻繁,讀行爲還沒到,緩存更新頻繁存在性能浪費。 同時若是寫高併發場景,壓力則直接壓到了DB上。併發

第二種方案異步

該方案仍然存在不一致問題。一個請求進行更新操做,另外一個請求進行查詢,第一個請求寫緩存還沒完成,讀請求先讀db後把緩存更新了,形成舊數據放到緩存了,若是最後沒能正確更新,數據有可能永遠是髒的。分佈式

第三種方案ide

源自於FB的方案,cache-aside pattern,策略是:高併發

  • 失效:應用從緩存取值,沒有獲得從數據庫獲取,成功後放入緩存。
  • 命中:應用從緩存中取數據,獲得後返回。
  • 更新:數據落庫,成功後,讓緩存失效。

簡單點說,FB的策略就是先更新DB,再刪除緩存。性能

固然這種方案一樣存在併發問題,兩個請求,緩存剛失效,一個寫一個讀,一樣讀請求會將舊值放入緩存。線程

可是這種概率極低 ,只有在讀操做時間大於寫操做時會存在,而數據庫特色是讀請求速度快於寫請求(停下來腦補1分鐘)。

固然針對於可能存在的併發問題仍是須要處理的,能夠採用異步延遲刪除策略,保證讀取以後進行緩存刪除。

若是刪除緩存失敗了怎麼辦?

  • 能夠採用重試(引入MQ兜底),存在引入MQ的成本。
  • 訂閱Binlog,達到雙通道保證。

固然若是對於一致性要求較高能夠直接開啓線程重試,本身開腦洞吧。

咱們在解決高併發場景下會引入自研的內存隊列,這個隊列的緩存是須要維護的,對於單機內存的數據一致性處理遠比分佈式緩存更復雜,就不展開談了。

相關文章
相關標籤/搜索