在高并发的场景下,大量的请求直接访问Mysql很容易造成性能问题。所以,我们都会用Redis来做数据的缓存,削减对数据库的请求。但是,mysql和Redis是两种不同的数据库,如何保证不同数据库之间数据的一致性就非常关键了。 一、导致
在高并发的场景下,大量的请求直接访问Mysql很容易造成性能问题。所以,我们都会用Redis来做数据的缓存,削减对数据库的请求。但是,mysql和Redis是两种不同的数据库,如何保证不同数据库之间数据的一致性就非常关键了。
“不管是先写MySQL数据库,再删除Redis缓存;还是先删除缓存,再写库,都有可能出现数据不一致的情况。
1)、如果先删除Redis缓存数据,然而还没有来得及写入MySQL,另一个线程就来读取;
2)、这个时候发现缓存为空,则去Mysql数据库中读取旧数据写入缓存,此时缓存中为脏数据;
3)、然后数据库更新后发现Redis和Mysql出现了数据不一致的问题。
1)、如果先写了库,然后再删除缓存,不幸的写库的线程挂了,导致了缓存没有删除;
2)、这个时候就会直接读取旧缓存,最终也导致了数据不一致情况;
3)、因为写和读是并发的,没法保证顺序,就会出现缓存和数据库的数据不一致的问题。
更多内容请关注公众号【程序员Style】,获取更多精彩内容!
在写库前后都进行redis.del(key)操作,并且设定合理的超时时间。
伪代码如下:
public void write( String key, Object data ){ redis.delkey(key); db.updateData(data); Thread.sleep(500); redis.delKey(key);}
“问题:这个500毫秒怎么确定的,具体该休眠多久时间呢?
比如:休眠1秒。
结合双删策略+缓存超时设置,这样最差的情况就是:
1>、涉及到更新的数据操作,利用Mysql binlog 进行增量订阅消费;
2>、将消息发送到消息队列;
3>、通过消息队列消费将增量数据更新到Redis上。
读取Redis缓存:热数据都在Redis上;
写Mysql:增删改都是在Mysql进行操作;
更新Redis数据:Mysql的数据操作都记录到binlog,通过消息队列及时更新到Redis上。
数据操作主要分为两种:
1>、一种是全量(将所有数据一次性写入Redis);
2>、一种是增量(实时更新)。
“这里说的是增量,指的是mysql的update、insert、delate变更数据。
读取binlog后分析 ,利用消息队列,推送更新各台的redis缓存数据。
1>、这样一旦MySQL中产生了新的写入、更新、删除等操作,就可以把binlog相关的消息推送至Redis;
2>、Redis再根据binlog中的记录,对Redis进行更新;
3>、其实这种机制,很类似MySQL的主从备份机制,因为MySQL的主备也是通过binlog来实现的数据一致性。
“
在高并发应用场景下,如果是对数据一致性要求高的情况下,要定位好导致数据和缓存不一致的原因。
解决高并发场景下数据一致性的方案有两种,分别是延时双删策略和异步更新缓存两种方案。
另外,设置缓存的过期时间是保证数据保持一致性的关键操作,需要结合业务进行合理的设置。
来源地址:https://blog.csdn.net/dreaming317/article/details/129844613
--结束END--
本文标题: Redis 和 MySQL 如何保持数据一致性?
本文链接: https://www.lsjlt.com/news/410087.html(转载时请注明来源链接)
有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341
下载Word文档到电脑,方便收藏和打印~
2024-05-21
2024-05-21
2024-05-21
2024-05-21
2024-05-21
2024-05-21
2024-05-21
2024-05-21
2024-05-21
2024-05-16
回答
回答
回答
回答
回答
回答
回答
回答
回答
回答
0