Redis缓存不一致问题如何解决

Redis缓存不一致问题如何解决

第一章 Redis之缓存可能遇到的问题


文章目录

  • Redis缓存不一致问题如何解决
  • 前言
  • 一、Redis是什么?
  • 二、使用Redis带来的缓存不一致问题
    • 1.搭建高可用的分布式缓存
  • 总结


前言

在单机、并发量小的情况下,我们可以直接让请求直接访问数据库,单机MySQL查询最大能够支持每秒1万左右的查询请求,3千左右的新增更改的请求。但是在高并发场面下,并发量远远大于这些请求,为了保证系统的安全和高可用,一般会使用缓存作为中间缓存层,避免请求直接访问数据库。


一、Redis是什么?

Redis是现在最受欢迎的非关系型数据库之一,是一个使用C语言编写的,开源的高性能的键值对数据库。
具有以下特点:

  • 基于内存运行、性能高效;
  • 支持分布式,理论上可以无限扩展;
  • key-value存储系统;
  • 开源的使用ANSI C语言编写、遵守BSD协议、支持网络、可基于内存可持久化的日志型、并且提供各种API;

相比于其他数据库,Redis具备的特点是:

  • C/S通讯模型;
  • 单进程单线程模型;
  • 丰富的数据类型;
  • 操作具有原子性;
  • 持久多种持久化方式;
  • 高并发读写(读110000次/s,写81000次/s);
  • 支持LUA脚本(redis分布式锁就是借助这个来实现的);

二、使用Redis带来的缓存不一致问题

在并发不高的情况下,可以先修改数据库,再更新缓存,这都是没有什么问题的。但是一旦并发量大了,上面说的情况可能就不合适了。具体如何解决呢?以下有几种方案。

1.搭建高可用的分布式缓存

  1. 使用Redis Sentinel 哨兵模式,监听集群内部的节点运行情况,保证缓存层的服务可用。
  2. 使用Redis Cluster 集群模式,和哨兵模式相似在都是为了保证服务的高可用,不同点在于集群中的从节点不提供服务,只提供当做数据备份,一旦主节点挂了会升级了新的主节点。
  3. 先写缓存、再写数据库;
    可能会出现缓存写成功,数据库写失败或者响应延迟,则下次读取缓存时,就出现了脏读。
    这个是写缓存的方式,本身就是错误额,需要改为先写数据库,把就缓存置为失效;读取数据时如果缓存不存在了,则读取数据库再写缓存;
  4. 先写数据库再写缓存;
    可能会出现数据库写成功,缓存写失败,导致下次请求的时候读取不到缓存层的数据。解决办法就是如果缓存读取失败,但是数据库读取成功,把数据写回缓存。
  5. 先更新数据库,在更新缓存;
    可能会出现更新数据库成功,redis宕机导致缓存更新失败。解决办法就是如果缓存读取失败,但是数据库读取成功,把数据写回缓存。
  6. 先删除缓存,再更新数据库;
    可能会出现线程1把缓存删除,此时正在更新数据库,但是还没有写到数据库,但是线程2来查询数据,缓存中没有,则查询到数据库中旧的数据并且更新到了数据库,造成了数据不一致的问题。
  7. 延迟双删,先删除缓存,再删除数据库;
    在更新完缓存之后,延迟几百毫秒之后再次删除缓存。虽然能够解决先删缓存再更新数据库的问题,但是无法确定需要具体延迟多久,有可能延迟的时间不够长还是会导致数据不一致问题,如果延迟过程,又浪费服务器资源;
  8. 订阅binlog日志;
    通过订阅数据库binlog日志也是也解决缓存不一致的一种好方案,这个实现逻辑相比前几种会更复杂一些,原理是服务去监听binlog日志,如果数据库发生了增删改,后端通过手写代码的方式去更新缓存,能够避免缓存中更新的为旧数据。

总结

以上就是我对如何解决缓存不一致问题的个人见解,如果有其他方案,欢迎评论区建言献策。

你可能感兴趣的:(redis,链表,算法,数据结构,redis)