MST
星途 面试题库

面试题:Redis数据一致性保障之读写策略

在高并发读写场景下,为了保障Redis与后端数据库的数据一致性,你会采取哪些读写策略?例如在读写操作时如何处理缓存与数据库的更新顺序,以及如何避免缓存穿透、缓存雪崩和缓存击穿问题对数据一致性的影响。
35.4万 热度难度
数据库Redis

知识考点

AI 面试

面试题答案

一键面试

读写策略

  1. 先更新数据库,再删除缓存:写操作时先更新数据库,成功后再删除 Redis 缓存。读操作时,先从 Redis 读取,若不存在则从数据库读取并回写 Redis。这样能保证在写操作后,下次读操作会从数据库获取最新数据并更新缓存。但在并发场景下可能存在短暂不一致,如在更新数据库和删除缓存之间有读请求,会读到旧缓存数据。
  2. 先删除缓存,再更新数据库:写操作先删除缓存,再更新数据库。读操作与上述类似。这种策略同样存在并发问题,如删除缓存后,还未更新数据库时,有读请求,会将旧数据重新写入缓存。可以通过设置缓存过期时间来降低不一致的时间窗口。

避免缓存穿透

  1. 布隆过滤器:在查询 Redis 前,先通过布隆过滤器判断数据是否存在。布隆过滤器能高效判断一个元素是否在集合中,若不存在则直接返回,不再查询数据库,减少数据库压力。但布隆过滤器存在误判率,即可能将不存在的数据误判为存在,不过误判率可通过调整参数控制。
  2. 空值缓存:当查询数据库发现数据不存在时,也将空值写入 Redis 缓存,并设置较短过期时间。下次查询同样数据时,直接从缓存获取空值,避免重复查询数据库。

避免缓存雪崩

  1. 设置不同过期时间:对 Redis 中的缓存数据设置不同的过期时间,避免大量缓存同时过期。可以在原有过期时间基础上,增加一个随机值,让过期时间分散开来。
  2. 使用熔断降级:当 Redis 大量请求失败,达到一定阈值时,开启熔断机制,直接返回兜底数据或错误提示,避免大量请求压垮数据库。同时记录相关日志,方便后续排查问题。
  3. 搭建多级缓存:可以采用本地缓存(如 Guava Cache)与 Redis 结合的方式。本地缓存作为一级缓存,先从本地缓存读取,若不存在再从 Redis 读取。这样在 Redis 出现问题时,本地缓存仍能提供部分数据服务,减轻数据库压力。

避免缓存击穿

  1. 互斥锁:在查询 Redis 未命中时,使用互斥锁(如 Redis 的 SETNX 命令实现),只允许一个线程去查询数据库并回写缓存,其他线程等待。获取锁的线程查询数据库并更新缓存后,释放锁,其他线程再从缓存获取数据。这种方式可能会导致大量线程等待,影响性能。
  2. 热点数据永不过期:对于热点数据不设置过期时间,保证一直从缓存获取数据。同时后台开启异步线程定时更新数据,或者在数据变化时主动更新缓存,确保数据一致性。