天天看點

mysql與redis資料一緻性問題探讨

前言

在我們的工作中為經常遇到 緩存中資料要和redis 資料一緻性問題,既然是兩份資料就一定存在不一緻的情況,但是咱們要根據咱們自行的業務場景來決定,資料不一緻時間、如果出現不一緻業務會有多大的影響等一些因素來決定資料同步方案是否能夠滿足業務要求。

資料同步方案

資料同步過程中,會存在短暫的延遲,這屬于正常的現象。在分布式架構中很難實作資料強一緻性.

弱一緻性: 主從之間資料允許不一緻性;

強一緻性: 主從之間資料必須一緻性; 如果實作 成本是非常高,會設計到一些鎖的技術,

最終一緻性:短暫的資料延遲是允許的,但是最終資料是需要一緻; —在分布式中做資料同步需要經過網絡傳輸的,網絡傳輸資料需要一定的時間,是以資料短暫的延遲是允許的,但是最終資料一定達成一緻。延遲是很難避免的,優化 減少延遲的時間。

同步方案

  1. 更新 mysql 資料,在手動清除 Redis 緩存 ,在重新查詢最新的資料同步到 Redis 中。
  2. 更新 mysql 資料,在采用 mq 異步的形式 同步資料到Redis 中。
  3. 基于訂閱 mysql binlog 采用 mq 異步的形式将資料同步到Redis 中。
  4. 訂閱 mysql binlog 檔案 異步的形式同步到 redis 中(canal 架構、阿裡開源)

    上述的隻是一些基本的處理方式。

    canal 解決mysql 與Redis資料同步方案(異步更新緩存)

    1.canal 僞裝成 mysql 從節點 訂閱 mysql 主節點的 binlog 檔案;

    2 .當我們的 mysql 主節點 binlog 檔案發生了變化,則将該 binlog 檔案發送給 canal 伺服器端;

    3.canal 伺服器端将該 binlog 檔案二進制轉化成 json 格式給 canal 用戶端;

    4.canal 用戶端在将該資料同步到 Redis/ES;

延時雙删政策

mysql與redis資料一緻性問題探讨

1.t1 線程先删除緩存;

2.t2 線程讀取緩存為 null,同步 db 資料到緩存中;

3.t1 線程更新 db 中的資料;

4.t3 線程查詢緩存中資料是舊資料;

如何解決該問題:延遲雙删政策

t1 線程更新完 DB 後,讓它 sleep 一段時間,再删除緩存 ;

延遲雙删缺點就是 第二次删除緩存時間很難控制

public void write( String key, Object data )
{ 
  redis.delKey( key );
  db.updateData( data );
  Thread.sleep( 500 );
  redis.delKey( key );
}      

總結