Redis學習(一):Redis的數據一致性


談談一致性

一致性是指數據保持一致,在分布式系統中,可以理解為多個節點中的數據是一致的。

  • 強一致性:用戶寫入什么數據,就可以讀出什么數據。這種一致性最符合用戶的直覺,用戶體驗好,但實現起來往往對系統的性能影響最大。
  • 弱一致性:在用戶寫入系統成功后,不承諾可以立即讀出寫入的數據,也不承諾多久數據可以達到一致,但會盡可能地保證到某個時間級別(比如秒級別)后,數據能夠達到一致狀態。
  • 最終一致性:最終一致性是弱一致性的一種特例,系統會保證在一定時間內,數據能夠達到一致的狀態。這里之所以將最終一致性單獨提出來,是因為它是弱一致性中非常推崇的一種一致性模型,也是業界在大型分布式系統的數據一致性上比較推崇的模型。

集中式redis緩存的三個經典的緩存模式

緩存可以提升性能,緩解數據庫壓力,但是緩存也會造成數據不一致的問題。那么一般是如何使用緩存的呢?

  • 旁路緩存模式,Cache-Aside Pattern
  • 讀寫穿透,Read-Through/Write-Through Pattern
  • 寫流程,Write behind

 Cache-Aside Pattern

旁路緩存模式的讀流程:先判斷是否命中緩存,未命中則查詢數據庫並更新緩存。

 

 

 旁路緩存模式寫流程:更新數據庫,然后刪除緩存。

 

 

Read-Through/Write-Through 讀寫穿透

在讀寫穿透模式中,服務端把緩存作為主要數據存儲。應用程序跟數據庫緩存交互,都是通過抽象緩存層完成的。

Read-Through讀流程:

 

 

 從緩存中讀數據,讀到直接返回

未讀到則查詢數據庫,然后更新緩存,再返回結果。

這個流程和旁路緩存模式很像,只是在查詢流程中增加了一層Cache-Provider,流程如下:

 

 

 我認為這層封裝目的是,讓使用者可以避免將未命中的查庫更新緩存的場景,反復編寫;使使用者更簡單的時候緩存模式。

Write-Through寫流程:

當發生寫請求時,也是由緩存抽象層完成數據源和緩存數據的更新,流程如下:

 

 

 Write behind(異步緩存寫入)

Write behind跟Read-Through/Write-Through有相似的地方,都是由Cache Provider來負責緩存和數據庫讀寫。它兩個又有很大的不同,讀寫穿透是同步更新緩存和數據庫,異步寫入緩存則是只更新緩存,不直接更新數據庫,通過批量異步的方式來更新數據庫。

 

 

 

這種方式下,緩存和數據庫的一致性不強,對一致性要求高的系統要謹慎使用。

但是它適合頻繁寫的場景,MySQL的InnoDB Buffer Pool機制就使用到這種模式。

三種模式的比較

  1、旁路緩存模式實現起來比較簡單,但是需要維護兩個數據存儲:

  • 一個是緩存
  • 一個是數據庫

  2、讀寫穿透模式的寫模式需要維護一個數據存儲(緩存),實現起來要復雜一些。

  3、異步寫模式與讀寫穿透模式相似,只是異步寫是異步的,讀寫穿透是同步的。

  4、異步寫的優點是直接操作內存速度快,多次操作可以合並為一次持久化到數據庫。缺點是數據可能會丟失,例如系統斷電。

Cache-Aside的問題

更新數據的時候,Cache-Aside是刪除緩存呢?還是應該更新緩存呢?

有些小伙伴會問,為什么Cache-Aside寫入的時候,是刪除緩存而不是更新緩存呢?下面來看個例子:

 

 操作的次序如下:

  1. 線程A先發起一個寫請求,先更新了數據庫
  2. 線程B又發起一個寫請求,又更新了數據庫
  3. 由於網絡原因,線程B先更新了緩存,然后線程A又更新了緩存。
  4. 這個時候,緩存中保存A的數據就是舊數據(數據庫中B更新的數據是新數據),數據庫不一致了,出現臟數據了。如果是刪除緩存就不會出現這個問題。

更新緩存還有兩個劣勢:

  1. 如果寫入的緩存值,是經過復雜計算才得到的話。更新頻率高的話,會浪費性能。
  2. 在寫多讀少的情況下,很多數據沒有被讀到,數據就又被更新了,也會浪費性能。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM