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

相关推荐
弥生赞歌1 小时前
MySQL 数据库集群高可用与可视化监控平台搭建实验报告
数据库·mysql
e***71671 小时前
mysql用户名怎么看
数据库·mysql
8***84821 小时前
macOS安装Redis
数据库·redis·macos
j***82701 小时前
MySQL 启动失败 (code=exited, status=1FAILURE) 异常解决方案
数据库·mysql
r***86981 小时前
【MySQL 的数据目录】
数据库·mysql·adb
8***J1821 小时前
SQL进阶——JOIN操作详解
数据库·sql·oracle
王景程2 小时前
升级Pixy CMUcam5 固件
mysql·android runtime
旷野说2 小时前
如何用 Redpanda + 本地事务,实现“发消息 + 写 DB” 的强一致性!
java·数据库·kafka
管理大亨2 小时前
Canal:企业数据实时同步的利器
数据库·mysql