MySQL數(shù)據(jù)實(shí)時(shí)同步Redis的方案全解析
將MySQL中的數(shù)據(jù)通過(guò)Canal同步到Redis,是一種比較常見(jiàn)的數(shù)據(jù)庫(kù)與緩存間增量數(shù)據(jù)同步的方案,核心思路是利用Canal解析MySQL的binlog,捕獲數(shù)據(jù)變更,然后更新到Redis。這樣做的好處是對(duì)業(yè)務(wù)代碼侵入小,能較好地保證數(shù)據(jù)一致性。

核心工作原理
Canal工作的核心是偽裝成MySQL的從庫(kù)(Slave)。
- 模擬從庫(kù)交互:Canal啟動(dòng)后,會(huì)模擬MySQL從庫(kù)的行為,向MySQL主庫(kù)(Master)發(fā)送一個(gè)
dump請(qǐng)求。 - 主庫(kù)推送Binlog:MySQL主庫(kù)接收到
dump請(qǐng)求后,會(huì)將自己的二進(jìn)制日志(Binary Log)推送給Canal。 - 解析與轉(zhuǎn)發(fā):Canal接收到原始的二進(jìn)制日志流后,會(huì)對(duì)其進(jìn)行解析,轉(zhuǎn)換成易于處理的對(duì)象,然后傳遞給下游模塊進(jìn)行存儲(chǔ)和消費(fèi)。
這個(gè)過(guò)程使得Canal能夠實(shí)時(shí)捕獲數(shù)據(jù)庫(kù)的變更(如INSERT、UPDATE、DELETE),從而實(shí)現(xiàn)數(shù)據(jù)的增量訂閱與消費(fèi)。
為了讓你能快速把握核心流程,這里用一個(gè)表格來(lái)匯總主要步驟和關(guān)鍵點(diǎn):
| 步驟 | 關(guān)鍵動(dòng)作 | 說(shuō)明/注意事項(xiàng) |
|---|---|---|
| 1. 環(huán)境準(zhǔn)備 | 開(kāi)啟MySQL Binlog | 必須設(shè)置為ROW模式,并配置server_id。 |
| 創(chuàng)建Canal數(shù)據(jù)庫(kù)用戶 | 授予SELECT, REPLICATION SLAVE, REPLICATION CLIENT權(quán)限。 | |
| 準(zhǔn)備Redis | 確保Canal服務(wù)器可訪問(wèn)Redis。 | |
| 2. 安裝配置Canal | 部署Canal Server | 可從官方GitHub倉(cāng)庫(kù)下載發(fā)布版。 |
修改canal.properties | 配置Canal服務(wù)模式,例如指定使用tcp模式或者與RabbitMQ、Kafka等消息隊(duì)列集成。 | |
修改instance.properties | 配置數(shù)據(jù)庫(kù)連接信息(地址、用戶名、密碼等)和binlog訂閱規(guī)則。 | |
| 3. 開(kāi)發(fā)數(shù)據(jù)處理邏輯 | 接收并解析binlog | 使用Canal客戶端或通過(guò)消息隊(duì)列消費(fèi)者(如監(jiān)聽(tīng)Kafka)獲取數(shù)據(jù)變更。 |
| 設(shè)計(jì)Redis數(shù)據(jù)格式 | 決定數(shù)據(jù)在Redis中的存儲(chǔ)格式(如String、Hash等)。 | |
| 寫入Redis | 根據(jù)解析出的數(shù)據(jù)操作類型(增、刪、改),執(zhí)行相應(yīng)的Redis寫入或刪除命令。 | |
| 4. 啟動(dòng)與驗(yàn)證 | 啟動(dòng)Canel及客戶端 | 先啟動(dòng)Canal Server,再啟動(dòng)你的客戶端程序。 |
| 測(cè)試數(shù)據(jù)變更 | 在MySQL中執(zhí)行增、刪、改操作,觀察Redis中數(shù)據(jù)是否按預(yù)期變化。 |
?? 操作細(xì)節(jié)與要點(diǎn)
1. 環(huán)境準(zhǔn)備:配置MySQL
- [mysqld] log-bin=mysql-bin # 開(kāi)啟binlog binlog-format=ROW # 選擇ROW模式[citation:4] server_id=1 # 配置一個(gè)唯一的server_id
- 創(chuàng)建Canal用戶并授權(quán):在MySQL中執(zhí)行以下命令:
CREATE USER 'canal'@'%' IDENTIFIED BY 'your_password'; GRANT SELECT, REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'canal'@'%'; FLUSH PRIVILEGES;
2. Canal安裝與配置
下載與解壓:從Canal的GitHub Release頁(yè)面下載所需版本的安裝包,然后解壓到目標(biāo)目錄。
Canal服務(wù)端口 canal.port = 11111 # 服務(wù)模式,如tcp, kafka, RocketMQ等[citation:6] canal.serverMode = tcp # 目的地集合,對(duì)應(yīng)instance配置的文件夾名 canal.destinations = example
主庫(kù)地址 canal.instance.master.address = 127.0.0.1:3306 # 數(shù)據(jù)庫(kù)用戶名 canal.instance.dbUsername = canal # 數(shù)據(jù)庫(kù)密碼 canal.instance.dbPassword = your_canal_password # 要監(jiān)聽(tīng)的表,支持正則表達(dá)式 canal.instance.filter.regex = .*\\..*
3. 開(kāi)發(fā)數(shù)據(jù)處理邏輯
Canal客戶端示例(Java偽代碼)展示了如何處理binlog并操作Redis:
// Canal客戶端監(jiān)聽(tīng)Binlog(偽代碼)
CanalConnector connector = CanalConnectors.newClusterConnector("127.0.0.1:2181", "example", "", "");
connector.connect();
connector.subscribe(".*\\..*");
while (true) {
Message message = connector.getWithoutAck(100);
for (CanalEntry.Entry entry : message.getEntries()) {
if (entry.getEntryType() == CanalEntry.EntryType.ROWDATA) {
CanalEntry.RowChange rowChange = CanalEntry.RowChange.parseFrom(entry.getStoreValue());
for (CanalEntry.RowData rowData : rowChange.getRowDatasList()) {
String tableName = entry.getHeader().getTableName();
// 根據(jù)表名和主鍵構(gòu)造Redis Key,這里假設(shè)第一列為主鍵
String key = "cache:" + tableName + ":" + rowData.getBeforeColumns(0).getValue();
if (rowChange.getEventType() == CanalEntry.EventType.DELETE) {
redis.del(key); // 刪除緩存[citation:6]
} else {
// 更新緩存:這里可以將rowData的AfterColumns序列化后存儲(chǔ)
redis.set(key, serialize(rowData.getAfterColumnsList())); // 更新緩存[citation:6]
}
}
}
}
}4. 啟動(dòng)與驗(yàn)證
d /your/target/directory/bin sh startup.sh
- 驗(yàn)證:
- 檢查Canal服務(wù)日志
logs/canal/canal.log,查看服務(wù)是否正常啟動(dòng)。 - 檢查實(shí)例日志
logs/example/example.log,查看實(shí)例運(yùn)行狀態(tài)和是否有數(shù)據(jù)同步。 - 在MySQL中執(zhí)行INSERT、UPDATE、DELETE操作,觀察Redis中對(duì)應(yīng)的key是否按預(yù)期變化。
- 檢查Canal服務(wù)日志
?? 常見(jiàn)問(wèn)題與技巧
- 數(shù)據(jù)格式設(shè)計(jì):同步到Redis時(shí),需合理設(shè)計(jì)Key和Value。Key通常包含表名和主鍵-6。Value可使用String存儲(chǔ)JSON序列化后的整行數(shù)據(jù),或用Hash存儲(chǔ)字段和值的映射。
- 冪等性處理:在網(wǎng)絡(luò)不穩(wěn)定或客戶端重啟的情況下,可能會(huì)收到重復(fù)的binlog消息。確保數(shù)據(jù)同步邏輯具有冪等性。
- 處理DDL語(yǔ)句:Canal可以解析DDL(如ALTER TABLE)。如果表結(jié)構(gòu)變更影響Redis中的數(shù)據(jù)格式,客戶端需能處理或觸發(fā)緩存重建。
- 性能考量:直接通過(guò)Canal TCP客戶端同步,在高并發(fā)下可能成為瓶頸。此時(shí)可引入消息隊(duì)列(如Kafka、RocketMQ) 解耦-6,Canal將變更事件發(fā)送到MQ,由消費(fèi)者異步處理并更新Redis。
- 使用現(xiàn)成平臺(tái):除了自建Canal集群,也可考慮使用CloudCanal這類數(shù)據(jù)平臺(tái),它提供了圖形化界面,簡(jiǎn)化了MySQL到Redis同步鏈路的創(chuàng)建和管理-1。
?? 總結(jié)
利用Canal同步MySQL數(shù)據(jù)到Redis,關(guān)鍵在于正確配置MySQL的Binlog,合理部署和配置Canal,并編寫可靠的數(shù)據(jù)處理和Redis寫入邏輯。引入消息隊(duì)列可以提升整體的可靠性和擴(kuò)展性。同時(shí),務(wù)必注意數(shù)據(jù)格式的設(shè)計(jì)和冪等性處理。
到此這篇關(guān)于MySQL數(shù)據(jù)實(shí)時(shí)同步Redis的方案全解析的文章就介紹到這了,更多相關(guān)mysql redis同步內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- Redis和數(shù)據(jù)庫(kù)的一致性(Canal+MQ) 的實(shí)現(xiàn)
- 使用Canal實(shí)現(xiàn)MySQL數(shù)據(jù)同步的完整指南
- canal實(shí)現(xiàn)mysql數(shù)據(jù)同步的詳細(xì)過(guò)程
- 兩個(gè)windows服務(wù)器使用canal實(shí)現(xiàn)mysql實(shí)時(shí)同步
- Canal實(shí)現(xiàn)MYSQL實(shí)時(shí)數(shù)據(jù)同步的示例代碼
- Canal進(jìn)行MySQL到MySQL數(shù)據(jù)庫(kù)全量+增量同步踩坑指南
- 基于Docker結(jié)合Canal實(shí)現(xiàn)MySQL實(shí)時(shí)增量數(shù)據(jù)傳輸功能
- 保證MySQL與Redis數(shù)據(jù)一致性的6種實(shí)現(xiàn)方案
- Redis與MySQL數(shù)據(jù)一致性問(wèn)題的策略模式及解決方案
- 詳解讓MySQL和Redis數(shù)據(jù)保持一致的四種策略
- Java使用Canal同步MySQL數(shù)據(jù)到Redis
- Linux寶塔面板使用Canal實(shí)現(xiàn)Mysql和Redis數(shù)據(jù)同步(圖文教程)
相關(guān)文章
詳解MySQL導(dǎo)出指定表中的數(shù)據(jù)的實(shí)例
這篇文章主要介紹了詳解MySQL導(dǎo)出指定表中的數(shù)據(jù)的實(shí)例的相關(guān)資料,希望通過(guò)本文能幫助到大家,需要的朋友可以參考下2017-09-09
MySQL?SQL預(yù)處理(Prepared)的語(yǔ)法實(shí)例與注意事項(xiàng)
所謂預(yù)編譯語(yǔ)句就是將此類SQL語(yǔ)句中的值用占位符替代,可以視為將 SQL語(yǔ)句模板化或者說(shuō)參數(shù)化,一般稱這類語(yǔ)句叫Prepared Statements,下面這篇文章主要給大家介紹了關(guān)于MySQL?SQL預(yù)處理(Prepared)的相關(guān)資料,需要的朋友可以參考下2022-01-01
mysql 5.7 數(shù)據(jù)庫(kù)安裝步驟個(gè)人總結(jié)
這篇文章主要介紹了mysql 數(shù)據(jù)庫(kù)安裝步驟個(gè)人總結(jié),需要的朋友可以參考下2017-09-09
MySQL常用字符串函數(shù)示例和場(chǎng)景介紹
MySQL提供了豐富的字符串函數(shù)幫助我們高效地對(duì)字符串進(jìn)行處理、轉(zhuǎn)換和分析,本文我將全面且深入地介紹MySQL常用的字符串函數(shù),并結(jié)合具體示例和場(chǎng)景,幫你熟練掌握這些實(shí)用工具,感興趣的朋友跟隨小編一起看看吧2025-07-07
mysql時(shí)間戳格式化函數(shù)from_unixtime使用的簡(jiǎn)單說(shuō)明
mysql中的FROM_UNIXTIME函數(shù)可以數(shù)據(jù)庫(kù)中整型類的時(shí)間戳格式化為字符串的日期時(shí)間格式,下面這篇文章主要給大家介紹了關(guān)于mysql時(shí)間戳格式化函數(shù)from_unixtime使用的簡(jiǎn)單說(shuō)明,需要的朋友可以參考下2022-08-08
MYSQL中SWITCH語(yǔ)句和循環(huán)語(yǔ)句舉例詳解
MySQL提供了多種循環(huán)語(yǔ)句來(lái)實(shí)現(xiàn)循環(huán)操作,其中包括while循環(huán)、loop循環(huán)、repeat循環(huán)和非標(biāo)準(zhǔn)的goto循環(huán),下面這篇文章主要給大家介紹了關(guān)于MYSQL中SWITCH語(yǔ)句和循環(huán)語(yǔ)句的相關(guān)資料,需要的朋友可以參考下2024-06-06
經(jīng)測(cè)試最好用的mysql密碼忘記的解決方法
經(jīng)測(cè)試最好用的mysql密碼忘記的解決方法...2007-06-06
MySQL每天自動(dòng)增加分區(qū)的實(shí)現(xiàn)
本文主要介紹了MySQL每天自動(dòng)增加分區(qū)的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-08-08

