MySQL数据实时同步Redis的方案全解析

 更新时间:2025年12月04日 10:05:17   作者:管理大亨  
Canal通过解析MySQL的binlog,实现数据增量同步到Redis,保持数据一致性,核心工作原理是Canal伪装成MySQL从库,模拟从库交互,获取并解析binlog,然后更新到Redis,该方案对业务侵入小,适用于实时数据同步场景,本文介绍MySQL数据实时同步Redis的方法,感兴趣的朋友一起看看吧

将MySQL中的数据通过Canal同步到Redis,是一种比较常见的数据库与缓存间增量数据同步的方案,核心思路是利用Canal解析MySQL的binlog,捕获数据变更,然后更新到Redis。这样做的好处是对业务代码侵入小,能较好地保证数据一致性。

核心工作原理

Canal工作的核心是伪装成MySQL的从库(Slave)

  • 模拟从库交互:Canal启动后,会模拟MySQL从库的行为,向MySQL主库(Master)发送一个dump请求。
  • 主库推送Binlog:MySQL主库接收到dump请求后,会将自己的二进制日志(Binary Log)推送给Canal。
  • 解析与转发:Canal接收到原始的二进制日志流后,会对其进行解析,转换成易于处理的对象,然后传递给下游模块进行存储和消费。

这个过程使得Canal能够实时捕获数据库的变更(如INSERTUPDATEDELETE),从而实现数据的增量订阅与消费。

为了让你能快速把握核心流程,这里用一个表格来汇总主要步骤和关键点:

步骤关键动作说明/注意事项
1. 环境准备开启MySQL Binlog必须设置为ROW模式,并配置server_id
创建Canal数据库用户授予SELECT, REPLICATION SLAVE, REPLICATION CLIENT权限。
准备Redis确保Canal服务器可访问Redis。
2. 安装配置Canal部署Canal Server可从官方GitHub仓库下载发布版。
修改canal.properties配置Canal服务模式,例如指定使用tcp模式或者与RabbitMQKafka等消息队列集成。
修改instance.properties配置数据库连接信息(地址、用户名、密码等)和binlog订阅规则。
3. 开发数据处理逻辑接收并解析binlog使用Canal客户端或通过消息队列消费者(如监听Kafka)获取数据变更。
设计Redis数据格式决定数据在Redis中的存储格式(如String、Hash等)。
写入Redis根据解析出的数据操作类型(增、删、改),执行相应的Redis写入或删除命令。
4. 启动与验证启动Canel及客户端先启动Canal Server,再启动你的客户端程序。
测试数据变更在MySQL中执行增、删、改操作,观察Redis中数据是否按预期变化。

🔧 操作细节与要点

1. 环境准备:配置MySQL

  • [mysqld] log-bin=mysql-bin # 开启binlog binlog-format=ROW # 选择ROW模式[citation:4] server_id=1 # 配置一个唯一的server_id
  • 创建Canal用户并授权:在MySQL中执行以下命令:
CREATE USER 'canal'@'%' IDENTIFIED BY 'your_password'; GRANT SELECT, REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'canal'@'%'; FLUSH PRIVILEGES;

2. Canal安装与配置

下载与解压:从Canal的GitHub Release页面下载所需版本的安装包,然后解压到目标目录。

 Canal服务端口
canal.port = 11111
# 服务模式,如tcp, kafka, RocketMQ等[citation:6]
canal.serverMode = tcp
# 目的地集合,对应instance配置的文件夹名
canal.destinations = example
 主库地址
canal.instance.master.address = 127.0.0.1:3306
# 数据库用户名
canal.instance.dbUsername = canal
# 数据库密码
canal.instance.dbPassword = your_canal_password
# 要监听的表,支持正则表达式
canal.instance.filter.regex = .*\\..*

3. 开发数据处理逻辑

Canal客户端示例(Java伪代码)展示了如何处理binlog并操作Redis:

// Canal客户端监听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();
                // 根据表名和主键构造Redis Key,这里假设第一列为主键
                String key = "cache:" + tableName + ":" + rowData.getBeforeColumns(0).getValue();
                if (rowChange.getEventType() == CanalEntry.EventType.DELETE) {
                    redis.del(key);  // 删除缓存[citation:6]
                } else {
                    // 更新缓存:这里可以将rowData的AfterColumns序列化后存储
                    redis.set(key, serialize(rowData.getAfterColumnsList()));  // 更新缓存[citation:6]
                }
            }
        }
    }
}

4. 启动与验证

d /your/target/directory/bin
sh startup.sh
  • 验证
    • 检查Canal服务日志 logs/canal/canal.log,查看服务是否正常启动。
    • 检查实例日志 logs/example/example.log,查看实例运行状态和是否有数据同步。
    • 在MySQL中执行INSERT、UPDATE、DELETE操作,观察Redis中对应的key是否按预期变化。

⚠️ 常见问题与技巧

  • 数据格式设计:同步到Redis时,需合理设计Key和Value。Key通常包含表名和主键-6。Value可使用String存储JSON序列化后的整行数据,或用Hash存储字段和值的映射。
  • 幂等性处理:在网络不稳定或客户端重启的情况下,可能会收到重复的binlog消息。确保数据同步逻辑具有幂等性。
  • 处理DDL语句:Canal可以解析DDL(如ALTER TABLE)。如果表结构变更影响Redis中的数据格式,客户端需能处理或触发缓存重建。
  • 性能考量:直接通过Canal TCP客户端同步,在高并发下可能成为瓶颈。此时可引入消息队列(如Kafka、RocketMQ) 解耦-6,Canal将变更事件发送到MQ,由消费者异步处理并更新Redis。
  • 使用现成平台:除了自建Canal集群,也可考虑使用CloudCanal这类数据平台,它提供了图形化界面,简化了MySQL到Redis同步链路的创建和管理-1。

💎 总结

利用Canal同步MySQL数据到Redis,关键在于正确配置MySQL的Binlog,合理部署和配置Canal,并编写可靠的数据处理和Redis写入逻辑。引入消息队列可以提升整体的可靠性和扩展性。同时,务必注意数据格式的设计和幂等性处理。

到此这篇关于MySQL数据实时同步Redis的方案全解析的文章就介绍到这了,更多相关mysql redis同步内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 详解MySQL导出指定表中的数据的实例

    详解MySQL导出指定表中的数据的实例

    这篇文章主要介绍了详解MySQL导出指定表中的数据的实例的相关资料,希望通过本文能帮助到大家,需要的朋友可以参考下
    2017-09-09
  • MySQL SQL预处理(Prepared)的语法实例与注意事项

    MySQL SQL预处理(Prepared)的语法实例与注意事项

    所谓预编译语句就是将此类SQL语句中的值用占位符替代,可以视为将 SQL语句模板化或者说参数化,一般称这类语句叫Prepared Statements,下面这篇文章主要给大家介绍了关于MySQL SQL预处理(Prepared)的相关资料,需要的朋友可以参考下
    2022-01-01
  • mysql 5.7 数据库安装步骤个人总结

    mysql 5.7 数据库安装步骤个人总结

    这篇文章主要介绍了mysql 数据库安装步骤个人总结,需要的朋友可以参考下
    2017-09-09
  • MySQL常用字符串函数示例和场景介绍

    MySQL常用字符串函数示例和场景介绍

    MySQL提供了丰富的字符串函数帮助我们高效地对字符串进行处理、转换和分析,本文我将全面且深入地介绍MySQL常用的字符串函数,并结合具体示例和场景,帮你熟练掌握这些实用工具,感兴趣的朋友跟随小编一起看看吧
    2025-07-07
  • mysql中datetime字段建立索引并比较大小详解

    mysql中datetime字段建立索引并比较大小详解

    MySQL数据库常用的时间类型有timestamp和datetime,两者主要区别是占用存储空间长度不一致、可存储的时间也有限制,下面这篇文章主要给大家介绍了关于mysql中datetime字段建立索引并比较大小的相关资料,需要的朋友可以参考下
    2022-12-12
  • mysql时间戳格式化函数from_unixtime使用的简单说明

    mysql时间戳格式化函数from_unixtime使用的简单说明

    mysql中的FROM_UNIXTIME函数可以数据库中整型类的时间戳格式化为字符串的日期时间格式,下面这篇文章主要给大家介绍了关于mysql时间戳格式化函数from_unixtime使用的简单说明,需要的朋友可以参考下
    2022-08-08
  • MYSQL中SWITCH语句和循环语句举例详解

    MYSQL中SWITCH语句和循环语句举例详解

    MySQL提供了多种循环语句来实现循环操作,其中包括while循环、loop循环、repeat循环和非标准的goto循环,下面这篇文章主要给大家介绍了关于MYSQL中SWITCH语句和循环语句的相关资料,需要的朋友可以参考下
    2024-06-06
  • Mysql中explain作用详解

    Mysql中explain作用详解

    这篇文章主要介绍了Mysql中explain的相关内容,涉及索引的部分知识,具有一定参考价值,需要的朋友可以了解下。
    2017-10-10
  • 经测试最好用的mysql密码忘记的解决方法

    经测试最好用的mysql密码忘记的解决方法

    经测试最好用的mysql密码忘记的解决方法...
    2007-06-06
  • MySQL每天自动增加分区的实现

    MySQL每天自动增加分区的实现

    本文主要介绍了MySQL每天自动增加分区的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-08-08

最新评论