redis緩存數據一致性的思考

1. 雙寫模式

做法順序:先寫數據庫,再寫緩存

雙寫模式

併發的問題:

併發的問題

由於卡頓等原因,導致寫緩存2在最前,寫緩存1在後面就出現了不一致

髒數據問題: 這是暫時性的髒數據問題,但是在數據穩定,緩存過期以後,又能得到最新的正確數據

讀到的最新數據有延遲:最終一致性

2. 失效模式

做法順序:先寫數據庫,在刪除緩存

失效模式

併發問題:

併發問題

由於網絡或者i/o問題導致第三個請求拿到了數據庫中數據:db-1,此時第二個請求數據庫寫更新db-1->db-2已完成,立刻刪除緩存,第三個請求又將緩存刷新成第一個請求時的數據

還是會出現髒數據問題:最終不一致性

解決方案: 無論是雙寫模式還是失效模式,都會導致緩存的不一致問題(多個實例同時更新)。

  1. 緩存數據加上過期時間,每隔一段時間觸發讀的主動更新
  2. 如果是菜單,商品介紹等基礎數據,也可以去使用canal訂閱binlog的方式(比較優秀)。
  3. 通過加鎖保證併發讀寫,寫寫的時候按順序排好隊。讀讀無所謂。所以適合使用讀寫鎖。

高併發緩存問題高併發緩存問題

1、緩存集中失效

緩存集中失效

將原來的固定過期時間,調整爲過期時間=基礎時間+隨機時間,讓緩存慢慢過期,避免瞬間全部過期對DB產生過大壓力。

2、緩存穿透

方案一:查存DB 時,如果數據不存在,預熱一個特殊空值到緩存中。這樣,後續查詢都會命中緩存,但是要對特殊值,解析處理。

方案二:構造一個BloomFilter過濾器,初始化全量數據,當接到請求時,在BloomFilter中判斷這個key是否存在,如果不存在,直接返回即可,無需再查詢緩存和DB

3、緩存雪崩

4、緩存熱點

將集中化流量打散,避免一個緩存節點過載。由於只有一個key,我們可以在key的後面拼上有序編號,比如key#01、key#02。。。key#10多個副本,這些加工後的key位於多個緩存節點上。 每次請求時,客戶端隨機訪問一個即可

5、緩存大Key

6、緩存數據一致性

緩存是用來加速的,一般不會持久化儲存。所以,一份數據通常會存在DB和緩存中,由此會帶來一個問題,如何保證這兩者的數據一致性。另外,緩存熱點問題會引入多個副本備份,也可能會發生不一致現象。

緩存數據一致性

方案一:當緩存更新失敗後,進行重試,如果重試失敗,將失敗的key寫入MQ消息隊列,通過異步任務補償緩存,保證數據的一致性。

方案二:設置一個較短的過期時間,通過自修復的方式,在緩存過期後,緩存重新加載最新的數據

7、數據併發競爭預熱

互聯網系統典型的特點就是流量大,一旦緩存中的數據過期、或因某些原因被刪除等,導致緩存中的數據爲空,大量的併發線程請求(查詢同一個key)就會一起併發查詢數據庫,數據庫的壓力陡然增加。

如果請求量非常大,全部壓在數據庫,可能把數據庫壓垮,進而導致整個系統的服務不可用。

數據併發競爭預熱

方案一:引入一把全局鎖,當緩存未命中時,先嚐試獲取全局鎖,如果拿到鎖纔有資格去查詢DB,並將數據預熱到緩存中。雖然client端發起的請求非常多,但是由於拿不到鎖只能處於等待狀態,當緩存中的數據預熱成功後再從緩存中獲取

緩存全局鎖

方案二:緩存數據創建多個備份,當一個過期失效後,可以訪問其他備份。

核心要素: 1. 讓訪問儘量命中緩存 2. 同時保持數據的一致性

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章