MySQL数据实时同步Redis全攻略

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

核心工作原理

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

  1. 模拟从库交互 :Canal启动后,会模拟MySQL从库的行为,向MySQL主库(Master)发送一个dump请求。

  2. 主库推送Binlog :MySQL主库接收到dump请求后,会将自己的二进制日志(Binary Log)推送给Canal。

  3. 解析与转发: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

    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:

java代码:

复制代码
// 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写入逻辑。引入消息队列可以提升整体的可靠性和扩展性。同时,务必注意数据格式的设计和幂等性处理。

相关推荐
倔强的石头_14 小时前
kingbase备份与恢复实战(二)—— sys_dump库级逻辑备份与恢复(Windows详细步骤)
数据库
jiayou642 天前
KingbaseES 实战:深度解析数据库对象访问权限管理
数据库
于眠牧北2 天前
MySQL的锁类型,表锁,行锁,MVCC中所使用的临键锁
mysql
李广坤3 天前
MySQL 大表字段变更实践(改名 + 改类型 + 改长度)
数据库
Turnip12024 天前
深度解析:为什么简单的数据库"写操作"会在 MySQL 中卡住?
后端·mysql
爱可生开源社区4 天前
2026 年,优秀的 DBA 需要具备哪些素质?
数据库·人工智能·dba
随逸1774 天前
《从零搭建NestJS项目》
数据库·typescript
加号35 天前
windows系统下mysql多源数据库同步部署
数据库·windows·mysql
シ風箏5 天前
MySQL【部署 04】Docker部署 MySQL8.0.32 版本(网盘镜像及启动命令分享)
数据库·mysql·docker
李慕婉学姐5 天前
Springboot智慧社区系统设计与开发6n99s526(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。
数据库·spring boot·后端