当前位置: 首页 > 后端技术 > Node.js

Redis与数据库数据一致性

时间:2023-04-03 19:57:58 Node.js

本文首发于公众号:程序员周先森。本平台不定期更新,喜欢我的文章,请关注我的微信公众号。说到Redis和Mysql双数据库的数据一致性,很多人第一个想到的方案就是将读请求和写请求序列化,串到一个内存队列中。但是这种方案有一个致命的缺点:读请求和写请求的序列化会大大降低系统的吞吐量,需要使用比正常多几倍的机器来支持一个在线请求。为什么会出现Redis和Mysql双数据库的数据一致性问题?其实我们可以考虑这样一个业务场景:我们需要更新一些数据,我们先更新数据库数据,然后清除Redis缓存中的数据。但是数据库更新操作成功了,但是redis异常清空了缓存,就会导致这样一种情况:数据库中的数据已经更新为最新的数据,但是redis缓存中的数据还是旧数据,而这个会发生Redis和Mysql双数据库的数据一致性问题。有喜欢投机取巧的朋友会想,那我先清空缓存中的旧数据,再把新数据写入数据库,最后更新缓存,不行吗?这种方式可能存在一个问题:我们已经成功的清除了Redis的缓存,但是在新的数据写入数据库之前发生了读请求,这会导致数据库中的旧数据重新存储到Redis中,然后将新数据写入数据库后,会发生同样的情况。Redis和Mysql双数据库的数据一致性问题。昨天讲了Redis分布式环境。其实上面提到在分布式环境下,数据的读写操作是并发操作,所以不能保证对一条数据的读写操作的执行顺序,所以可能会出现读操作先于的情况执行写操作,会出现脏数据,造成数据一致性问题。这个时候我们就需要考虑我们读到的数据是否是强一致性数据。比如账户余额必须是强一致数据,然后读取数据库。如果对读取数据的实时性要求不是很严格,比如排行榜等,可以直接读取Redis数据。如果机器并发不高,读取数据先从Redis读取。如果缓存中的数据不存在,则选择从数据库中获取,将从数据库中获取的数据写入Redis。写入数据则相反。先清空Redis缓存数据,再将数据写入数据库。如果是简单数据,此时可以实时写入Redis进行读取操作。如果是需要多表连表查询的数据,那么可以暂时不写入Redis,等有查询操作的时候再写入Redis。高并发呢?高并发情况下,读取数据操作同上,先从Redis读取。但是,写入数据的操作与之前的方法不同。在高并发的情况下,写数据先写入Redis,然后周期性的从Redis写入Mysql。在高并发的情况下,需要注意每次请求读取数据都需要在超时时间内返回数??据。如果数据更新频繁,可能会导致Redis积压一系列的更新操作,导致大量的读数据请求超时,最后大量的读数据请求全部推送到数据库,导致缓存崩溃,严重的可能导致数据库宕机。这时候解决办法一般是通过增加机器来增加吞吐量,或者先临时返回一个旧数据给客户端。所以在这里我们实际上有一个非常明确的计划。常见的解决方案有两种:Redis作为缓存服务器,一般作为缓存有两个目的:快速请求处理和降低I/O频率。降低I/O的频率,其实就是在刚才说的高并发的情况下,将数据实时写入数据库,等数据积累到一定程度,再定时写入数据库。请求的快速处理是在处理读请求时,从Redis中有限获取。Redis支持高并发操作,所以处理速度非常快。如果Redis中没有数据,会去数据库中查询,然后写入Redis中的缓存中,这样二次读取就可以直接从缓存中取数据了。第二种方案其实就是异步异步缓存。Redis缓存了流行的数据,增删改查所有在Mysql中的操作。只要Mysql有insert、update、delete操作,就可以通过kafka或rabbitMQ等第三方消息推送工具推送binlog相关的消息。在Redis中,Redis通过解析binlog中的数据来更新Redis缓存中的数据,Mysql中的主从备份机制也是通过binlog来实现数据一致性的。本文由博客多发平台OpenWrite发布!