MySQL 數據同步到 Redis 緩存- so Easy -
來源:dongshao.blog.csdn.net/article/details/107190925
本文介紹 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 中,從而達到同步的效果
-
方案分析:
-
這種方案適合於讀多寫少,並且不存併發寫的場景
-
因爲 MySQL 觸發器本身就會造成效率的降低,如果一個表經常被操作,這種方案顯示是不合適的
演示案例
- 下面是 MySQL 的表
- 下面是 UDF 的解析代碼
- 定義對應的觸發器
二、方案 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 中,從而達到同步的效果
-
例如下面是一個雲數據庫實例分析:
-
雲數據庫與本地數據庫是主從關係。雲數據庫作爲主數據庫主要提供寫,本地數據庫作爲從數據庫從主數據庫中讀取數據
-
本地數據庫讀取到數據之後,解析 Bin log,然後將數據寫入寫入同步到 Redis 中,然後客戶端從 Redis 讀數據
- 這個技術方案的難點就在於: 如何解析 MySQL 的 Bin Log。但是這需要對 binlog 文件以及 MySQL 有非常深入的理解,同時由於 binlog 存在 Statement/Row/Mixedlevel 多種形式,分析 binlog 實現同步的工作量是非常大的
Canal 開源技術
canal 是阿里巴巴旗下的一款開源項目,純 Java 開發。基於數據庫增量日誌解析,提供增量數據訂閱 & 消費,目前主要支持了 MySQL(也支持 mariaDB)
開源參考地址有:https://github.com/liukelin/canal_mysql_nosql_sync
工作原理(模仿 MySQL 複製):
canal 模擬 mysql slave 的交互協議,僞裝自己爲 mysql slave,向 mysql master 發送 dump 協議
mysql master 收到 dump 請求,開始推送 binary log 給 slave(也就是 canal)
canal 解析 binary log 對象(原始爲 byte 流)
架構:
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 中同步到緩存中。
但是在實際開發中可能有人會用下面的方案:
-
1、客戶端有數據來了之後,先將其保存到 Redis 中,然後再同步到 MySQL 中
-
2、這種方案本身也是不安全 / 不可靠的,因此如果 Redis 存在短暫的宕機或失效,那麼會丟失數據
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/4cISZQiN8csuYdh0afoxWA