Redis(十四)——缓存问题

 1、缓存穿透

(1)问题描述

缓存和数据库中都没有数据。例如利用不存在的key恶意攻击,导致数据库压力过大

(2)解决方案

  • 接口层增加参数校验,用户鉴权,id非法拦截。
  • 从缓存取不到数据,数据库也没有查到,返回值在缓存设置短时间默认值或者空。
  • 布隆过滤器快速判断key是否存在数据库。

2、缓存击穿

(1)问题描述

1个key过期时,访问量巨大

(2)解决方案

  • 热点数据永不过期
  • 互斥锁,第一个线程访问key的时候就锁住,等查询数据库返回后,把值写到缓存再释放锁,后续请求直接取缓存。

3、缓存雪崩

(1)问题描述

大量key同时过期或者缓存服务器宕机也算雪崩

(2)解决方案

  • 热点数据永不过期
  • 缓存数据的过期时间设置随机
  • 分布式缓存集群,确保高可用,例如redis-cluster

4、缓存和数据库一致性

(1)问题描述

数据库与缓存更新,可能会出现数据不一致的情况。写和读是并发的,无论是「先写数据库再删缓存」还是「先删缓存再写数据库」都可能出现数据不一致的情况。

  • 如果删除了缓存Redis,还没有来得及写库MySQL,另一个线程就来读取,发现缓存为空,则去数据库中读取数据写入缓存,此时缓存中为脏数据。
  • 如果先写了库,在删除缓存前,写库的线程宕机了,没有删除掉缓存,则也会出现数据不一致情况。

(2)解决方案

  • 先删缓存再写数据库:一般情况用这个就够了。这种操作出现数据不一致的条件是:读缓存时缓存失效,而且并发着有一个写操作,读操作必需在写操作前进入数据库操作,而又要晚于写操作更新缓存。 但实际上写操作会比读操作慢很多,还要锁表,因此满足数据不一致的概率不大。
  • 队列+失败重试:写库成功后删除缓存失败,将key发到MQ中消费,失败继续发MQ,直到成功。缺点是对业务代码造成大量入侵。
  • 订阅binlog:订阅MySQL的写操作日志,更新redis。

 

posted @ 2023-02-08 00:10  守林鸟  阅读(41)  评论(0编辑  收藏  举报