微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

通俗易懂讲解mysql和Redis数据一致性

MysqL和redis数据同步方案

MysqL集群主从复制 解决单点故障问题

2、高可用方案 对外提供是一个主节点,投票

3、横向扩展cluster集群 对外提供多个主节点

怎么优化单个主节点的处理能力?

主节点master 发生了写操作,数据进行了变更,binlog里面将会有记录

这时候从节点slave 开启io线程 读取master节点的binlog日志,然后生成一个中继日志 relay log,再由 sql线程读取这个relay log日志,回放,写入到从节点中,这样就完成了同步。

在这里插入图片描述

MysqL 主从复制的方式

在这里插入图片描述

1、异步复制

当客户端写入数据到master节点之后,就立马返回结果给客户端,当然了,此时也在binlog日志的内容写入到 slave节点的relay log中继日志里面

2、半同步复制

当客户端写入数据到master节点之后,先不急就将结果返回到客户端,而是先等待,先把binlog日志里面的变化内容写入到slave节点中,然后再返回结果信息给客户端

这样就解决一个客户端A写数据到 master节点,同时又有一个客户端B来读,此时读的就是slave节点,如果是异步的方式,那么此时可能数据还没有同步到slave节点,这样读的数据可能就会不一致了。

但是引入了一个问题:写延迟

单主节点,异步复制,在这种情况下怎么优化处理能力?

1、数据库代理

一个数据库中间件作为路由

在这里插入图片描述

2、redisMysqL同步

先写redis,再异步去写MysqL,最后让MysqL复写给redis

先写redis,redis要加一个过期时间:
为什么要加过期时间:
1、如果redis挂了,那么等redis好了之后,再重写就可以了
2、如果MysqL挂了,那么redis存进去之后也就马上就消失了,这样这条写入操作也相当于废掉了

在这里插入图片描述


在这里插入图片描述

在这里插入图片描述

双写不一致问题,先别考虑数据库和缓存挂的问题,只考虑更新和删除这两个操作失败的情况

最初级的数据库和缓存数据不一致问题:就是删除缓存这个操作失败了,也就是这个操作没有生效。
解决思路一:
删除缓存,再更新数据库,如果数据库更新失败了,则缓存中因为没有数据,就会去读数据库,因为数据库更新失败了,就还是旧值,这样就不会导致数据库和缓存中的数据不一致。

读写并发数据库和缓存不一致的场景

在这里插入图片描述


在这里插入图片描述


在这里插入图片描述


在这里插入图片描述


在这里插入图片描述


当队列中读请求 从队列中出来的时候,会去MysqL中读取数据,然后将读取到的数据,更新到redis中,这个操作其实是有点耗时的,因此,如果有多个读请求,不需要将所有的读请求都放到队列中,因为读请求都会执行 先读 然后 更新到redis的操作的!!!

所以如果队列里面有读请求了,这时又来了很多相同商品id的读请求,这时是没必要进队列的,只需要在外面一直循环,不断的读取Redis中的数据就可以了,如果在200ms 还没有读到数据,就直接去MysqL中取数据,取到之后就返回回去

在这里插入图片描述


在这里插入图片描述


如果一个队列中居然会积压100个商品的库存的修改操作,每个库存修改操作都要花费10ms完成,那么最后一个商品的读请求就会等待1s的时间,才能得到数据,这样读请求长期阻塞。
所以一定要做压力测试。

如果最繁忙的时候,也都积压了10个更新请求,那还可以!
但如果积压了100多个更新请求,那么就要加机器了,

怎么对同一个商品的读写请求路由到同一个队列中

可以按照请求的某个参数做hash路由

热点商品的路由问题

热点商品的请求全部打到某个队列中,可能造成某台机器压力过大

如果更新频率不大,这个问题的影响不大,但这个机器的负载确实会高一些

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐