赞
踩
目录
方法二:订阅Mysql的Binlog文件(可借助Canal来进行)
MySQL 支持事务,在需要保证一致性的操作中使用事务。通过将 Redis 和 MySQL 操作放在同一个事务中,并使用 ACID(原子性、一致性、隔离性和持久性)的特性,可以保证 Redis 和 MySQL 数据的一致性。
CanalServer会伪装成MysqlServer从库,去订阅MysqlServer主库的Binlog文件
Canal启动的时候会配置对应的消息MQ(RabbitMQ, RocketMQ, Kafka), 监听到Binlog文件有变化是,会把变化的sql语句转换成json格式,并作为消息内容发送到MQ中
项目中只要监听对应MQ,就能拿到Binlog改动的内容,Json数据中有明确的操作类型(CURD), 以及对应的数据。把对应数据同步到redis即可
缺点1:canal订阅Binlog的整个操作过程是单线程的,所以面临超高并发的情况下,性能可能不太出色。当然可以部署多个Canal 与 多个消费者,但是要注意消息重复消费问题,做好幂等性校验
优点1:即使人为改数据库,也会监听到,并且也会同步
优点2:异步同步,不会对接口返回有格外延迟
基于消息队列的同步方案,通常是将 MySQL 的更新操作通过消息队列发送到一个或多个 Redis 服务器,然后 Redis 服务器根据消息队列中的消息更新缓存中的数据。这种方案相对较为灵活,可以根据实际需求选择合适的消息队列,比如 RabbitMQ、Kafka、RocketMQ 等。
具体实现可以分为以下步骤:
配置消息队列,比如 RabbitMQ。可以参考 RabbitMQ 官方文档 进行配置。
在 MySQL 数据库中配置触发器,将更新操作通过消息队列发送出去。以下是一个 MySQL 触发器的示例代码:
- CREATE TRIGGER sync_data AFTER INSERT ON table1
- FOR EACH ROW
- BEGIN
- INSERT INTO rabbitmq_queue (message) VALUES (NEW.message);
- END;
上述代码将在 table1 表中插入新数据时,向名为 rabbitmq_queue 的消息队列中插入一条消息,消息内容为 NEW.message。
在 Redis 服务器上监听消息队列,当有新消息到来时,更新缓存中的数据。以下是一个 Java 代码的示例:
代码使用了 RabbitMQ 的 Java 客户端库,通过监听名为 rabbitmq_queue 的消息队列来更新 Redis 缓存中的数据。
- ConnectionFactory factory = new ConnectionFactory();
- factory.setHost("localhost");
- Connection connection = factory.newConnection();
- Channel channel = connection.createChannel();
-
- channel.queueDeclare("rabbitmq_queue", false, false, false, null);
-
- Consumer consumer = new DefaultConsumer(channel) {
- @Override
- public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
- String message = new String(body, "UTF-8");
- // 更新 Redis 缓存中的数据
- jedis.set("key", message);
- }
- };
-
- channel.basicConsume("rabbitmq_queue", true, consumer);
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。