天天看點

使用緩存redis(cache-aside)保證資料的一緻性

  1. 項目中常常會涉及到緩存的使用,但是引入緩存會帶來一緻性問題,需要考慮資料一緻性處理。首先看一下操作邏輯,

    查詢邏輯:

  2. 使用緩存redis(cache-aside)保證資料的一緻性
  3. 更新或者删除邏輯
  4. 使用緩存redis(cache-aside)保證資料的一緻性
  5. 在項目中,如果是cache-aside pattern模式,則會考慮使用先更新DB,再去删除cache的操作,原因分析如下:

    同時寫資料庫以及緩存資料,任何一個更新失敗都會造成資料不一緻。另外事務都成功,無論是先更新緩存還是再更新資料庫,還是先更新資料庫再更新緩存,這兩種情況在并發的情況下也很容易出現雙寫不成功,操作時序如下圖

  1. 如果使用更新模式,先更新DB再更新Cache則會帶來髒資料,原因如圖:
  2. 使用緩存redis(cache-aside)保證資料的一緻性
  3. 假設A、B兩個線程,A先更新資料庫後 B再更新資料庫,然後分别進行更新緩存,但是B先更新緩存成功,A後更新緩存成功,這樣就導緻資料庫是最新的資料但是緩存中是舊的髒資料。
  4. 如果使用更新模式,先更新Cache再更新DB則會帶來髒資料,原因如圖:
  5. 使用緩存redis(cache-aside)保證資料的一緻性
  6. 理由如上
  7. 如果使用删除模式,先删除cache,再去更新DB,時序圖如圖:
  8. 使用緩存redis(cache-aside)保證資料的一緻性
  9. 當有寫線程先失效了Cache,讀線程過來未讀取到,則去請求DB,此時DB還沒有更新完,傳回了舊資料并重新緩存,則下一次通路的時候,緩存中依舊是髒資料。
  10. 如果使用删除模式,先更新DB,再去删除Cache,是最優方案,時序圖如下:
  11. ​注意:該種方案也有可能出現髒資料可能,但是機率極低,工業界推薦使用該方式進行緩存。​

    ​ 何時出現髒資料?
    1. 讀線程讀取Cache,此時Cache剛好失效
    2. 寫線程執行速度要比讀線程執行快(一般情況,計算機中讀是比寫快很多的)
    3. 讀線程最後更新Cache
  1. 資料一緻性問題是很經典的問題,對于QPS小于4K的可以采用以上模式。以上是個人的一點拙見,如有不周,懇請指正。

繼續閱讀