MySQL 與 Redis 緩存的同步方案

本文介紹MySQL與Redis緩存的同步的兩種方案mysql

  • 方案1:經過MySQL自動同步刷新Redis,MySQL觸發器+UDF函數實現
  • 方案2:解析MySQL的binlog實現,將數據庫中的數據同步到Redis

方案1(UDF)

  • 場景分析:當咱們對MySQL數據庫進行數據操做時,同時將相應的數據同步到Redis中,同步到Redis以後,查詢的操做就從Redis中查找
  • 過程大體以下:
  • 在MySQL中對要操做的數據設置觸發器Trigger,監聽操做
  • 客戶端(NodeServer)向MySQL中寫入數據時,觸發器會被觸發,觸發以後調用MySQLUDF函數
  • UDF函數能夠把數據寫入到Redis中,從而達到同步的效果

圖片

  • 方案分析:
  • 這種方案適合於讀多寫少,而且不存併發寫的場景
  • 由於MySQL觸發器自己就會形成效率的下降,若是一個表常常被操做,這種方案顯示是不合適的
演示案例

下面是MySQL的表git

圖片

下面是UDF的解析代碼github

圖片

定義對應的觸發器sql

image.png

image.png

圖片

方案2(解析binlog)

在介紹方案2以前咱們先來介紹一下MySQL複製的原理,以下圖所示:數據庫

  • 主服務器操做數據,並將數據寫入Bin log
  • 從服務器調用I/O線程讀取主服務器的Bin log,而且寫入到本身的Relay log中,再調用SQL線程從Relay log中解析數據,從而同步到本身的數據庫中

圖片

方案2就是:緩存

  • 上面MySQL的整個複製流程能夠總結爲一句話,那就是:從服務器讀取主服務器Bin log中的數據,從而同步到本身的數據庫中
  • 咱們方案2也是如此,就是在概念上把主服務器改成MySQL,把從服務器改成Redis而已(以下圖所示),當MySQL中有數據寫入時,咱們就解析MySQL的Bin log,而後將解析出來的數據寫入到Redis中,從而達到同步的效果。(搜索公衆號民工哥技術之路,回覆「1024」,送你一份技術寶典)

image.png

例以下面是一個雲數據庫實例分析:安全

  • 雲數據庫與本地數據庫是主從關係。雲數據庫做爲主數據庫主要提供寫,本地數據庫做爲從數據庫從主數據庫中讀取數據
  • 本地數據庫讀取到數據以後,解析Bin log,而後將數據寫入寫入同步到Redis中,而後客戶端從Redis讀數據

圖片

這個技術方案的難點就在於:如何解析MySQL的Bin Log。可是這須要對binlog文件以及MySQL有很是深刻的理解,同時因爲binlog存在Statement/Row/Mixedlevel多種形式,分析binlog實現同步的工做量是很是大的服務器

Canal開源技術

canal是阿里巴巴旗下的一款開源項目,純Java開發。基於數據庫增量日誌解析,提供增量數據訂閱&消費,目前主要支持了MySQL(也支持mariaDB)架構

開源參考地址有:https://github.com/liukelin/c...\_mysql\_nosql\_sync併發

工做原理(模仿MySQL複製):
  • canal模擬mysql slave的交互協議,假裝本身爲mysql slave,向mysql master發送dump協議
  • mysql master收到dump請求,開始推送binary log給slave(也就是canal)
  • canal解析binary log對象(原始爲byte流)

image.png

架構:

  • 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能夠百度搜索

下面是運行拓撲圖

圖片

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

圖片

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

圖片

附加

本文上面所介紹的都是從MySQL中同步到緩存中。可是在實際開發中可能有人會用下面的方案:客戶端有數據來了以後,先將其保存到Redis中,而後再同步到MySQL中 這種方案自己也是不安全/不可靠的,所以若是Redis存在短暫的宕機或失效,那麼會丟失數據

圖片

做者 | 江南、董少
來源 | https://dongshao.blog.csdn.ne...

相關文章
相關標籤/搜索