MySQL 與 Redis 快取的同步方案

wwwhjw1688com1622871-9999發表於2021-03-17

MySQL與Redis快取的同步的兩種方案

方案1:通過MySQL自動同步重新整理Redis,MySQL觸發器+UDF函式實現

方案2:解析MySQL的binlog實現,將資料庫中的資料同步到Redis

一、方案1(UDF)
場景分析: 當我們對MySQL資料庫進行資料操作時,同時將相應的資料同步到Redis中,同步到Redis之後,查詢的操作就從Redis中查詢

過程大致如下:

在MySQL中對要操作的資料設定觸發器Trigger,監聽操作
客戶端(NodeServer)向MySQL中寫入資料時,觸發器會被觸發,觸發之後呼叫MySQL的UDF函式
UDF函式可以把資料寫入到Redis中,從而達到同步的效果
圖片

一步一圖,帶你走進 Netty 的世界!

方案分析:
這種方案適合於讀多寫少,並且不存併發寫的場景
因為MySQL觸發器本身就會造成效率的降低,如果一個表經常被操作,這種方案顯示是不合適的
演示案例

下面是MySQL的表
圖片

下面是UDF的解析程式碼
圖片

誰動了我的主機?活用history命令

定義對應的觸發器
圖片

圖片

圖片

二、方案2(解析binlog)
在介紹方案2之前我們先來介紹一下MySQL複製的原理,如下圖所示:

主伺服器運算元據,並將資料寫入Bin log
從伺服器呼叫I/O執行緒讀取主伺服器的Bin log,並且寫入到自己的Relay log中,再呼叫SQL執行緒從Relay log中解析資料,從而同步到自己的資料庫中
圖片

攜手阿里雲送一波超大福利!不僅有低價ECS,更有機械鍵盤、AirPods Pro等好禮!

方案2就是:

上面MySQL的整個複製流程可以總結為一句話,那就是:從伺服器讀取主伺服器Bin log中的資料,從而同步到自己的資料庫中
我們方案2也是如此,就是在概念上把主伺服器改為MySQL,把從伺服器改為Redis而已(如下圖所示),當MySQL中有資料寫入時,我們就解析MySQL的Bin log,然後將解析出來的資料寫入到Redis中,從而達到同步的效果
圖片

例如下面是一個雲資料庫例項分析:

雲資料庫與本地資料庫是主從關係。雲資料庫作為主資料庫主要提供寫,本地資料庫作為從資料庫從主資料庫中讀取資料
本地資料庫讀取到資料之後,解析Bin log,然後將資料寫入寫入同步到Redis中,然後客戶端從Redis讀資料
圖片

這個技術方案的難點就在於: 如何解析MySQL的Bin Log。但是這需要對binlog檔案以及MySQL有非常深入的理解,同時由於binlog存在Statement/Row/Mixedlevel多種形式,分析binlog實現同步的工作量是非常大的
Canal開源技術
canal是阿里巴巴旗下的一款開源專案,純Java開發。基於資料庫增量日誌解析,提供增量資料訂閱&消費,目前主要支援了MySQL(也支援mariaDB)

開源參考地址有:github.com/liukelin/canal_mysql_no...

工作原理(模仿MySQL複製):

canal模擬mysql slave的互動協議,偽裝自己為mysql slave,向mysql master傳送dump協議
mysql master收到dump請求,開始推送binary log給slave(也就是canal)
canal解析binary log物件(原始為byte流)
圖片

萬字長文:助你攻破 JAVA NIO 技術壁壘

架構:
eventParser (資料來源接入,模擬slave協議和master進行互動,協議解析)
eventSink (Parser和Store連結器,進行資料過濾,加工,分發的工作)
eventStore (資料儲存)
metaManager (增量訂閱&消費資訊管理器)
server代表一個canal執行例項,對應於一個jvm
instance對應於一個資料佇列 (1個server對應1..n個instance)
instance模組:
圖片

大致的解析過程如下:
parse解析MySQL的Bin log,然後將資料放入到sink中
sink對資料進行過濾,加工,分發
store從sink中讀取解析好的資料儲存起來
然後自己用設計程式碼將store中的資料同步寫入Redis中就可以了
其中parse/sink是框架封裝好的,我們做的是store的資料讀取那一步
圖片

更多關於Cancl可以百度搜尋
下面是執行拓撲圖
圖片

奇奇怪怪的大佬:理髮店小弟到阿里P10

MySQL表的同步,採用責任鏈模式,每張表對應一個Filter。 例如zvsync中要用到的類設計如下:
圖片

下面是具體化的zvsync中要用到的類, 每當新增或者刪除表時,直接進行增刪就可以了
圖片

三、附加
本文上面所介紹的都是從MySQL中同步到快取中。但是在實際開發中可能有人會用下面的方案:客戶端有資料來了之後,先將其儲存到Redis中,然後再同步到MySQL中 這種方案本身也是不安全/不可靠的,因此如果Redis存在短暫的當機或失效,那麼會丟失資料

圖片

本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章