97 基于Binlog实现MySQL与Redis数据一致性问题

97 基于Binlog实现MySQL与Redis数据一致性问题,第1张

mysql 与Redis 数据一致性问题 直接将Redis清空

中间件 canal框架 基于 docker环境构建

canal 框架 原理:

<u>https://gitee.com/mirrors/canal?utm_source=alading&utm_campaign=repo</u>

canal 框架原理

1,canal伪装成mysql从节点 订阅mysql 主节点的binlog文件

2,当我们的mysql 主节点 binlog 文件发生了变化,则将binlog 文件发送给canal服务器端

3,canal 服务器端将该binlog 文件二进制转换成json格式给canal客户端

4,canal客户端在将改数据同步到Redis/ES

基于Binlog 开启方式

1.mysql 开启binlog 文件配置

windows 配置

查询 my.ini配置文件位置

C:\ProgramData\MySQL\MySQL Server 5.7

2, linux mysql

安装canal

进入容器

编辑配置文件

重启canal

Docker-compose 构建canal

canal.instance.mysql.slaveId:slaveId不能与mysql的serverId一样

canal.instance.master.address:mysql地址

canal.instance.dbUsername:mysql账号

canal.instance.dbPassword:mysql密码

最近项目中,有个功能点是利用redis的发布订阅机制,进行服务器本地缓存数据同步。

由于redis发布订阅功能的可靠性较差,在项目中出现了有服务器没有订阅成功问题,以及服务器订阅消息不及时,导致部分业务受到影响。所以将redis通知本地缓存的机制改为了使用redis做二级缓存。

虽然Redis能够实现发布/订阅的功能,但是有如下缺点,所以选用前需谨慎考虑

和常规的MQ不同,redis实现的发布/订阅模型消息无法持久化,一经发布,即使没有任何订阅方处理,该条消息就会丢失

即发布方不会确保订阅方成功接收

广播机制无法通过添加多个消费方增强消费能力,因为这和发布/订阅模型本身的目的是不符的.广播机制的目的是一个一个发布者被多个订阅进行不同的处理

由于Redis发布/订阅模型存在的缺陷,所以使用前需要考虑如下几点

1.对于消息处理可靠性要求不强

2.消费能力无需通过增加消费方进行增强

————————————————

原文链接: https://blog.csdn.net/weixin_32394085/article/details/105006123

应用Redis实现数据的读写,同时利用队列处理器定时将数据写入mysql,此种情况存在的问题主要是如何保证mysql与redis的数据同步,二者数据同步的关键在于mysql数据库中主键,方案是在redis启动时去mysql读取所有表键值存入redis中,往redis写数据时,对redis主键自增并进行读取,若mysql更新失败,则需要及时清除缓存及同步redis主键。

String tbname = "login"

//获取mysql表主键值--redis启动时

long id = MySQL.getID(tbname)

//设置redis主键值--redis启动时

redisService.set(tbname, String.valueOf(id))

System.out.println(id)

long l = redisService.incr(tbname)

System.out.println(l)

Login login = new Login()

login.setId(l)

login.setName("redis")

redisService.hmset(String.valueOf(login.getId()), login)

boolean b = MySQL.insert("insert into login(id,name) values(" + login.getId() + ",'" + login.getName() + "')")

/**

*

* 队列处理器更新mysql失败:

*

* 清除缓存数据,同时主键值自减

*/

if (!b){

redisService.delKeyAndDecr(tbname, "Login:"+String.valueOf(login.getId()))

}

System.out.println(redisService.exists("Login:"+String.valueOf(login.getId())))

System.out.println(redisService.get(tbname))


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/8710619.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-20
下一篇 2023-04-20

发表评论

登录后才能评论

评论列表(0条)

保存