MST

星途 面试题库

面试题:缓存设计之高级难度:移动应用高并发场景下缓存一致性保证

在一个高并发的移动社交应用中,多个用户可能同时读取和更新缓存中的动态信息。请描述你将如何设计缓存机制以保证缓存数据与数据库数据的一致性,同时尽量减少缓存穿透、缓存雪崩和缓存击穿问题的发生。
26.9万 热度难度
后端开发缓存设计

知识考点

AI 面试

面试题答案

一键面试

保证缓存与数据库一致性

  1. 读写策略
    • 读操作:先从缓存读取数据,若缓存命中则直接返回;若缓存未命中,从数据库读取数据,然后将数据写入缓存,并返回给客户端。这样可以尽量减少对数据库的直接读取压力。
    • 写操作
      • 先更新数据库,再删除缓存:这是较为常用的方法。先确保数据库中的数据是最新的,然后删除缓存,下次读取时就会从数据库重新加载最新数据到缓存。但存在并发问题,比如在删除缓存前,另一个线程读取了旧的缓存数据,不过这种情况概率相对较小。
      • 先删除缓存,再更新数据库:可能会出现数据库更新失败,但缓存已删除,导致数据不一致问题,所以需要结合重试机制或事务来确保数据库更新成功。
  2. 缓存版本控制:给缓存数据设置版本号,每次数据库更新时,同时更新版本号。读取缓存时,不仅读取数据,还读取版本号,若发现版本号与预期不符,则重新从数据库加载数据并更新缓存和版本号。

减少缓存穿透问题

  1. 布隆过滤器:在查询数据前,先通过布隆过滤器判断数据是否存在。布隆过滤器可以快速判断一个元素是否在集合中,几乎不会漏判,但可能会误判。如果布隆过滤器判断数据不存在,就直接返回,不再查询数据库,从而避免大量无效查询穿透到数据库。
  2. 缓存空值:当查询数据库发现数据不存在时,也将空值缓存起来,并设置一个较短的过期时间,这样后续相同的查询就可以直接从缓存获取空值,而不会穿透到数据库。

减少缓存雪崩问题

  1. 设置不同过期时间:避免大量缓存同时过期。给缓存设置随机的过期时间,在一个合理的时间区间内波动,这样可以分散缓存过期的时间点,降低同一时间大量缓存失效的风险。
  2. 热点数据不过期:对于一些频繁访问的热点数据,不设置过期时间,或者通过后台线程定时更新缓存,保证数据的实时性。
  3. 构建多级缓存:比如采用本地缓存(如 Ehcache)和分布式缓存(如 Redis)相结合的方式。当分布式缓存出现雪崩时,本地缓存可以继续提供服务,减轻数据库压力,给系统恢复争取时间。

减少缓存击穿问题

  1. 互斥锁:在缓存失效的瞬间,只允许一个线程去查询数据库并更新缓存,其他线程等待。获取锁的线程查询数据库后更新缓存,然后释放锁,其他线程再从缓存获取数据。可以使用 Redis 的 SETNX 命令实现简单的互斥锁。
  2. 热点数据不过期:同缓存雪崩中热点数据不过期的方法,对于可能导致缓存击穿的热点数据,不设置过期时间,通过其他机制保证数据的实时性。