Redis做缓存的几种模式以及缓存雪崩、缓存击穿、缓存穿透分别是什么,怎么解决

本文详细介绍了服务端缓存的不同模式,包括cacheaside(旁路缓存)、readthrough、writethrough和writebehind,以及如何处理缓存穿透、击穿和雪崩问题。同时讨论了缓存一致性问题及其解决方案,如MySQL与Redis之间的数据同步策略。
摘要由CSDN通过智能技术生成

怎么做

缓存可以建立在客户端也可以建立在服务端(注意这里是广义的客户端、服务端,服务A向服务B发请求,那么A就是客户端

理论上来将每个服务端都应该给自己建立缓存,因为微服务要有一定的互不信任原则(请求先到你,你做过校验了,我不一定信)

四种模式

cache aside(旁路缓存)

最常用方式,就是先去看缓存有没有,有就返回,没有就去数据库读。
写的话直接写数据库去,然后删除缓存。
为啥不更新缓存而是删除缓存? 因为更新容易造成时序性问题:
thread1更新mysql为4 -> thread2更新mysql为2 -> thread2更新缓存为2 -> thread1更新缓存为4

read through

起一个中间服务,客户端就查你这个代理,不知道查的是缓存还是数据库。一切和缓存、数据库的交道都由这个代理来做。

write through

也是起了一个中间服务,只要发起写请求,代理就直接写数据库,然后同步更新redis。一般和read through搭配使用。
但这个对缓存压力比较大,只要更新了数据就得一同更新redis,对比旁路缓存是删除缓存数据的

write behind

和write through一样,只不过写完数据库不立即写缓存,而是异步的写缓存(找一个合适时间点,比如低负载时候;或者累计几个一并写入)。

缓存穿透

缓存和数据库都没有这个数据,一般是被攻击了,有人频繁查询不存在的key。
解决方法:

  • 接口层设置校验,key异常的直接拦截
  • 缓存和数据库都没有的数据,在缓存里写key-null,然后设置一个较短的过期时间,比如30s(防止之后真有这个key写进数据库了,缓存数据还是null)
  • 布隆过滤器。一个key会被多个hash函数映射,假设这些位置都被点亮认为这个数据可能是存在的,可以去数据库查一下。要是有的hash位置没被点亮,就是拒绝。这样对时间空间都好,就是不完全准确。

缓存击穿

缓存没有,数据库有。通常是某一时刻,一个热点数据过期,恰好此时并发用户特别多来访问这个数据,结果都打到数据库上了。
解决方法:

  • 被持续访问的数据适当延长过期时间
  • 加互斥锁,多线程来发现缓存没有,就会竞争去数据库查。只有一个线程去查了,查完更新缓存,其他线程直接查缓存了就。

缓存雪崩

缓存没有数据库有。通常是缓存中大批数据同时过期了,而这时候大量查询过来了,让数据库压力过大甚至宕机。
解决方法:

  • 设置随机过期时间,别一起过期
  • 加互斥锁,多线程来发现缓存没有,就会竞争去数据库查。只有一个线程去查了,查完更新缓存,其他线程直接查缓存了就。

缓存一致性问题

就是redis和mysql数据不一致了,主要有三种方式。但其实兜兜转转说一堆假设产品对一致性要求极高,尽量别用缓存

mysql更新后不管redis,靠过期时间兜底

实现起来成本低,但是这就得容忍一段时间的数据库和缓存不一致问题了。

mysql更新后,操作redis

操作分为两种一种是更新另一种是删除,更倾向于使用后一种。假设删除失败了,会退化成第一种方案。

异步将mysql的更新同步给redis

redis作为mysql一个slave,订阅mysql的binlog日志,解析日志后更新回redis。这种方式要搭建一个同步服务,成本大一点,但是解耦了,更新mysql后不需要做额外的工作,比较适合数据过期时间长甚至是不过期的场景(这是原因,是因为这种场景,才会用到这种订阅binlog模式)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值