热门标签 | HotTags
当前位置:  开发笔记 > 后端 > 正文

数据库面试题:Redis如何保证数据一致性

Redis缓存如何保证数据一致性一.Redis概述redis是一个内存数据库,因此数据基本上都存在于内存当中但是Redis会定时以追加或者快照的方式刷新到硬盘中.由于redis是一




Redis缓存如何保证数据一致性

一. Redis概述


  • redis是一个内存数据库, 因此数据基本上都存在于内存当中
  • 但是Redis会定时以追加或者快照的方式刷新到硬盘中.
  • 由于redis是一个内存数据库, 所以读取写入的速度是非常快的, 所以经常被用来做数据, 页面等的缓存。

二.为什么会出现数据不一致


2.1 一般的读写模式

当Redis作为缓存的时候,经典的读写模式如下:

(1)读的时候,先读缓存,缓存没有的话,那么就读数据库,然后取出数据后放入缓存,同时返回响应

(2)更新的时候,先删除缓存,然后再更新数据库

问题:


  • 上述的读写模式看似没有任何问题,但是在高并发及多线程的情况下会出现数据不一致的情况。

2.2 单库产生数据不一致

发生条件:


  • 同一时间发生了并发读写请求,比如A(写) ,B (读),2个请求

发生过程:


  • A发送更新请求,先删除缓存,删除缓存后由于某种原因被阻塞
  • B发送读请求,此时缓存无效,直接读取数据库,再将数据库的数据更新到缓存中
  • 之后A再写数据库
  • 这时候缓存和数据库就产生了数据不一致的问题,缓存中的数据就是脏数据

2.2 主从同步,读写分离产生数据不一致

主从同步,读写分离:实际上就是读数据库都是读从库,写数据库是写主库,然后进行主从同步。

过程:


  • A请求发送一个写操作到服务端,第一步就会淘汰掉cache
  • A请求写主数据库,往主数据库写了最新的数据。
  • B请求发送一个读操作,读cache,因为cache淘汰,所以为空
  • B请求继续读DB,这个时候读的是从库,此时主从同步还没同步成功。读出脏数据,然后脏数据写入cache
  • 最后数据库主从同步完成。这时候还是会发生数据不一致的情况。

三. 数据不一致解决方案


3.1 缓存双淘汰法


  • 在写库前后都进行redis.del(key)操作,并且设定合理的超时时间。这样最差的情况是在超时时间内存在不一致,当然这种情况极其少见,可能的原因就是服务宕机。此种情况可以满足绝大多数需求。 当然这种策略要考虑redis和数据库主从同步的耗时,所以在第二次删除前最好休眠一定时间,比如500毫秒,这样毫无疑问又增加了写请求的耗时。

3.2 异步淘汰缓存


  • 增加一个线下的读取binlog异步淘汰缓存模块,在读取binlog总的数据,然后进行异步淘汰。

过程:

MySQL binlog增量发布订阅消耗+消息队列+增量数据更新到redis

1)读取请求转到Redis:热数据基本上在Redis

2)写入请求转到MySQL:增加删除和 修改MySQL

3)更新Redis数据:MySQ数据操作binlog更新为Redis

在这里插入图片描述



推荐阅读
author-avatar
金色阳光CC
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有