天天看點

寫入緩存政策無法更改_緩存模式以及緩存的資料一緻性

(給資料分析與開發加星标,提升資料技能)

轉自:GitHub  作者: stephanie Tang

stephanietang.github.io/2020/04/13/cache-pattern/

緩存由于其高性能,支援高并發的特性,在高并發的項目中不可或缺。被大家廣泛使用的有Redis,Memcached等。 本文主要探讨幾種常見的緩存的讀寫模式,以及如何來保證緩存和資料庫的資料一緻性。

Cache-Aside

Cache-Aside可能是項目中最常見的一種模式。它是一種控制邏輯都實作在應用程式中的模式。緩存不和資料庫直接進行互動,而是由應用程式來同時和緩存以及資料庫打交道。Cache-Aside的名字正展現了這個模式,Cache在應用的一旁(aside)。 讀資料時

  1. 程式需要判斷緩存中是否已經存在資料。
  2. 當緩存中已經存在資料(也就是緩存命中,cache hit),則直接從緩存中傳回資料
  3. 當緩存中不存在資料(也就是緩存未命中,cache miss),則先從資料庫裡讀取資料,并且存入緩存,然後傳回資料
寫入緩存政策無法更改_緩存模式以及緩存的資料一緻性

寫資料時,我們可以有以下兩種政策: 第一種政策:

  1. 更新資料庫
  2. 更新緩存

但這種政策有線程安全的問題,可能出現緩存和資料庫不一緻。試想有兩個寫的線程,線程A和線程B

  1. A寫資料庫
  2. B後于A寫資料庫
  3. B寫緩存
  4. A寫緩存
  5. 緩存和資料庫中的資料不一緻,緩存中的是髒資料

要解決線程安全的問題,我們可以加鎖,不過實作起來比較麻煩,是以我們不考慮這種寫政策,而使用第二種政策。 第二種政策:

  1. 更新資料庫
  2. 删除緩存中對應的資料
寫入緩存政策無法更改_緩存模式以及緩存的資料一緻性

那麼這種寫政策會有線程安全的問題嗎?有,試想一下有兩個線程,線程A讀,線程B寫

  1. A讀資料,由于未命中那麼從資料庫中取資料
  2. B寫資料庫
  3. B删除緩存
  4. A由于網絡延遲比較慢,将髒資料寫入緩存

但是這種情況可能性非常的小,需要同時滿足很多條件,近乎不太可能發生,是以我們一般都采用這種寫政策。另外可以對緩存中的資料設定合适的過期時間,即使發生的髒資料的情況,也不會發生很長時間。

應用場景

應用于緩存不支援Read-Through/Write-Through的系統。

優點

  • 緩存僅僅儲存被請求的資料,屬于懶加載模式(Lazy Loading),和下文的Write-Through模式相比,避免了任何資料都被寫入緩存造成緩存頻繁的更新。

缺點

  • 當發生緩存未命中的情況時,則會比較慢,因為要經過三個步驟:查詢緩存,從資料庫讀取,寫入緩存。
  • 複雜的邏輯都在應用程式中,如果實作微服務,多個微服務中會有重複的邏輯代碼

Read-Through/Write-Through

這種模式中,應用程式将緩存作為主要的資料源,而資料庫對于應用程式是透明的,更新資料庫和從資料庫的讀取的任務都交給緩存來代理了,是以對于應用程式來說,簡單很多。

Read-Through

由緩存配置一個讀子產品,它知道如何将資料庫中的資料寫入緩存。在資料被請求的時候,如果未命中,則将資料從資料庫載入緩存。

寫入緩存政策無法更改_緩存模式以及緩存的資料一緻性

Write-Through 緩存配置一個寫子產品,它知道如何将資料寫入資料庫。當應用要寫入資料時,緩存會先存儲資料,并調用寫子產品将資料寫入資料庫。

寫入緩存政策無法更改_緩存模式以及緩存的資料一緻性

應用場景 Read Through/Write Through适用于寫入之後經常被讀取的應用。

優點

  • 緩存不存在髒資料
  • 相比較Cache-Aside懶加載模式,讀取速度更高,因為較少因為緩存未命中而從資料庫中查找
  • 應用程式的邏輯相對簡單

缺點

  • 對于總是寫入卻很少被讀取的應用,那麼Write-Through會非常浪費性能,因為資料可能更改了很多次,卻沒有被讀取,白白的每次都寫入緩存造成寫入延遲。

除了Write-Through以外,我們還有另外的兩種寫模式可以和Read-Through一起來配合使用,分别是Write-Back和Write-Around。

Write-Back

又叫做Write-Behind。和Write-Through寫入的時機不同,Write-Back将緩存作為可靠的資料源,每次都隻寫入緩存,而寫入資料庫則采用異步的方式,比如當資料要被移除出緩存的時候再存儲到資料庫或者一段時間之後批量更新資料庫。

寫入緩存政策無法更改_緩存模式以及緩存的資料一緻性

應用場景 讀寫效率都非常好,寫的時候因為異步存儲到資料庫,提升了寫的效率,适用于讀寫密集的應用。

優點

  • 寫入和讀取資料都非常的快,因為都是從緩存中直接讀取和寫入。
  • 對于資料庫不可用的情況有一定的容忍度,即使資料庫暫時不可用,系統也整體可用,當資料庫之後恢複的時候,再将資料寫入資料庫。

缺點

  • 有資料丢失的風險,如果緩存挂掉而資料沒有及時寫到資料庫中,那麼緩存中的有些資料将永久的丢失了

Write-Around

和Write-Through不同,更新的時候隻寫入資料庫,不寫入緩存,結合Read-Through或者Cache-Aside使用,隻在緩存未命中的情況下寫緩存。

寫入緩存政策無法更改_緩存模式以及緩存的資料一緻性

應用場景 适合于隻寫入一次而很少被讀取的應用。

優點

  • 相比較Write-Through寫入的時候的效率較高,如果資料寫入後很少被讀取,緩存也不會被沒用到的資料占滿。

缺點

  • 如果資料會寫入多次,那麼可能存在緩存和資料庫不一緻

推薦閱讀   點選标題可跳轉 為什麼 MySQL 的自增主鍵不單調也不連續 ; 分布式定時任務排程系統技術選型 ; 17 條避坑指南!谷歌工程師的資料庫經驗貼 ;

看完本文有收獲?請轉發分享給更多人

關注「資料分析與開發」加星标,提升資料技能

寫入緩存政策無法更改_緩存模式以及緩存的資料一緻性

好文章,我在看❤️