Redis数据一致性问题的三种解决方案

缓存由于其高并发和高性能的特性,已经在项目中被广泛使用 。在读取缓存方面,大家没啥疑问,都是按照下图的流程来进行业务操作 。1、首先redis是什么Redis(Remote Dictionary Server ),是一个高性能的基于Key-Value结构存储的NoSQL开源数据库 。大部分公司采用Redis来实现分布式缓存,用来提高数据查询效率 。
2、为什么会选Redis在Web应用发展的初期,系统的访问和并发并不高,交互也比较少 。但随着业务的扩大,访问量的提升,使得服务器负载和关系型数据库出现瓶颈,而导致瓶颈的源头,主要体现在磁盘IO上 。随着互联网的进一步发展,对系统性能有了更高的要求,Redis的出现,解决了很多问题 。至于我们为什么要选择Redis,我总结为以下六个原因:
1)、基于内存存储,可以降低对关系型数据库的访问频次,从而缓解数据库压力
2)、数据IO操作能支持更高级别的QPS,官方发布的指标是10W;
3)、提供了比较多的数据存储结构,比如string、list、hash、set、zset等等 。
4)、采用单线程实现IO操作,避免了并发情况下的线程安全问题 。
5)、可以支持数据持久化,避免因服务器故障导致数据丢失的问题
6)、Redis还提供了更多高级功能,比如分布式锁、分布式队列、排行榜、查找附近的人等功能,为更复杂的需求提供了成熟的解决方案 。
3、 应用场景缓存,作为Key-Value形态的内存数据库,Redis 最先会被想到的应用场景便是作为数据缓存
分布式锁,分布式环境下对资源加锁
分布式共享数据,在多个应用之间共享
排行榜,自带排序的数据结构(zset)
消息队列,pub/sub功能也可以用作发布者 / 订阅者模型的消息

Redis数据一致性问题的三种解决方案

文章插图
4、redis用作缓存时4.1、作为缓存使用流程缓存由于其高并发和高性能的特性,已经在项目中被广泛使用 。在读取缓存方面,大家没啥疑问,都是按照下图的流程来进行业务操作 。
Redis数据一致性问题的三种解决方案

文章插图
4.2、数据性一致性问题例如我们使用Redis来作为缓存时,让请求先访问到Redis,而不是直接访问数据库 。而在这种业务场景下,可能会出现缓存和数据库数据不一致性的问题 。
在更新的时候,操作缓存和数据库无疑就是以下四种可能之一:
  • 先更新缓存,再更新数据库
  • 先更新数据库,再更新缓存
  • 先删除缓存,再更新数据库
  • 先更新数据库,再删除缓存
4.2.1、先更新缓存,再更新数据库
Redis数据一致性问题的三种解决方案

文章插图
如果我成功更新了缓存,但是在执行更新数据库的那一步,服务器突然宕机了,那么此时,我的缓存中是最新的数据,而数据库中是旧的数据 。
脏数据就因此诞生了,并且如果我缓存的信息(是单独某张表的),而且这张表也在其他表的关联查询中,那么其他表关联查询出来的数据也是脏数据,结果就是直接会产生一系列的问题 。
4.2.2、先更新数据库,在更新缓存
Redis数据一致性问题的三种解决方案

文章插图
只有等到缓存过期之后,才能访问到正确的信息 。那么在缓存没过期的时间段内,所看到的都是脏数据 。
以上两图中只要执行第二步时失败了,就必然会产生脏数据 。
4.2.3、先删除缓存,在更新数据库这种方式在没有高并发的情况下,是可能保持数据一致性的 。
Redis数据一致性问题的三种解决方案

文章插图
如果只有第一步执行成功,而第二步失败,那么只有缓存中的数据被删除了,但是数据库没有更新,那么在下一次进行查询的时候,查不到缓存,只能重新查询数据库,构建缓存,这样其实也是相对做到了数据一致性 。
但如果是处于读写并发的情况下,还是会出现数据不一致的情况:
Redis数据一致性问题的三种解决方案

文章插图
执行完成后,明显可以看出,1号用户所构建的缓存,并不是最新的数据,还是存在问题的
4.2.4、先更新数据库,在删除缓存如果更新数据库成功了,而删除缓存失败了,那么数据库中就会是新数据,而缓存中是旧数据,数据就出现了不一致情况 。


推荐阅读