<返回更多

Redis 和 MySQL 数据一致性详解

2023-03-09    重庆源码时代
加入收藏

在实际开发过程中,我们经常会遇见在高并发的的情况下,大量的请求访问MySQL数据库,会造成性能安全问题。所以,我们很多时候会把数据写入到redis里面,用作缓存来减少数据库的压力,但是Redis 和 MySQL是两种不同类型的数据库,我们要怎样去保证它们之间的数据是一致性的呢?

数据不一致的原因

当数据并发量非常大的情况下,用户的并发访问会对数据库的安全造成极大的安全隐患。

因此,我们就需要使用到Redis来做一个缓存的操作,可以让用户请求先访问Redis,而不直接访问到数据库。

然后只是读取缓存操作的话,一般不会对数据库产生很大的问题,主要是涉及到数据的更新问题,数据库和缓存更新,就很容易出Redis 和 MySQL的数据一致性问题。

产生的问题

其实不管我们是先删除缓存,再写库还是先写库,再删除缓存,都有可能会出现数据不一致的情况:

先删除缓存

如果是删除Redis的缓存数据,在数据还没有写入MySQL数据库的时候,另一个线程就来读取缓存,就会发现这个缓存为空,然后会直接去MySQL数据库读取旧的数据并把数据写入缓存里面。这样,就会造成数据库更新后发现Redis和MySQL里面的数据不一致。

后删除缓存

如果是先把数据写入了MySQL里面,正准备删除缓存的时候,突然写入数据库的线程发生异常,导致了缓存并没有被删除。这个时候,另一个线程就会直接读取到旧的缓存数据,这也会导致Redis和MySQL里面的数据不一致。

解决方案

延时双删策略

这个方案主要是在写入数据的时候都进行缓存的删除操作,并且给它设置合理的超时时间。

具体操作:

1.先删除缓存 再写数据库

2.休眠几百毫秒 再次删除缓存

这么做的目的主要是为了确保这个请求结束后,有可能造成的缓存脏数据。这个方案最关键的其实还是给缓存设置过期时间,只要达到过期时间,缓存删除,如果后面还有读的请求,就会从数据库中读取新的值并且回填到缓存里面,这个是保证最终一致性的解决方案。

异步更新缓存

这个方案是基于Mysql binlog的同步机制,在设计的更新的数据操作的时候,利用Mysql binlog进行增量的订阅消费,然后将消息发送给消息队列,再通过消息队列消费将增量数据更新到Redis上面。

具体操作:

1.读取Redis缓存 写Mysql

2.更新Redis缓存数据,Mysql 的数据操作都记录到binlog,再通过下次队列及时更新到Redis缓存上

这样的好处是一旦Mysql 中发生了新的写入、更新、删除等操作,丢会通过binlog把相关消息推送到Redis里面,Redis会根据binlog中的操作记录对Redis进行更新,而且这种方案和Mysql 的主从备份很相像,毕竟Mysql 的主从备份也是通过binlog来实现的数据的一致性的。

总结

最后,在当前分布式高并发众多的场景下,解决高并发场景下数据一致性的方案有两种,分别是延时双删策略和异步更新缓存两种方案。

声明:本站部分内容来自互联网,如有版权侵犯或其他问题请与我们联系,我们将立即删除或处理。
▍相关推荐
更多资讯 >>>