MST

星途 面试题库

面试题:缓存设计下内存数据库与缓存技术的数据一致性保障

当内存数据库(如Redis)与关系型数据库配合使用作为缓存时,如何保证高并发场景下的数据一致性?请详细阐述可能出现的问题及对应的解决方案,包括但不限于缓存穿透、缓存雪崩、缓存击穿等情况。
45.1万 热度难度
后端开发缓存设计

知识考点

AI 面试

面试题答案

一键面试

可能出现的问题及解决方案

缓存穿透

  • 问题描述:查询一个不存在的数据,由于缓存中没有,每次都会去数据库查询,若大量这样的请求,会给数据库带来巨大压力,甚至压垮数据库。
  • 解决方案
    • 布隆过滤器:在查询数据库前,使用布隆过滤器判断数据是否存在。布隆过滤器可以快速判断一个元素一定不存在或者可能存在。如果布隆过滤器判断不存在,则直接返回,不会查询数据库;如果判断可能存在,再去查询数据库并将结果存入缓存。
    • 空值缓存:当查询数据库发现数据不存在时,也将空值缓存起来,并设置较短的过期时间,这样后续相同查询直接从缓存返回空值,减少对数据库的查询压力。

缓存雪崩

  • 问题描述:大量缓存数据在同一时间过期,导致大量请求同时访问数据库,使数据库压力骤增,甚至可能导致数据库崩溃。
  • 解决方案
    • 随机过期时间:给缓存设置过期时间时,采用随机值,避免大量缓存集中过期。例如原本设置过期时间为1小时,可以在50分钟到70分钟之间随机设置过期时间。
    • 二级缓存:使用两层缓存,一级缓存设置较短过期时间,二级缓存设置较长过期时间。当一级缓存过期时,先从二级缓存获取数据,同时异步更新一级缓存,减少对数据库的访问频率。
    • 缓存预热:在系统上线前,提前将热点数据加载到缓存中,并设置合理的过期时间,避免上线后大量缓存同时过期。

缓存击穿

  • 问题描述:热点数据的缓存过期瞬间,大量请求同时访问,这些请求都会去查询数据库,给数据库带来巨大压力。
  • 解决方案
    • 互斥锁:在缓存过期时,只允许一个线程去查询数据库并更新缓存,其他线程等待。查询到数据并更新缓存后,其他线程再从缓存获取数据。可以使用分布式锁(如Redis的SETNX命令实现简单的分布式锁)来保证同一时间只有一个线程能查询数据库。
    • 永不过期:对于热点数据设置永不过期,同时采用异步线程定时更新缓存数据,这样可以避免缓存过期瞬间的高并发问题。但要注意异步更新缓存时数据一致性的问题,需确保更新过程中的数据正确性。

数据一致性保证

  • 双写一致性问题:在数据更新时,先更新数据库再更新缓存,或者先更新缓存再更新数据库,都可能因为中间步骤出现异常导致数据不一致。
  • 解决方案
    • 先更新数据库,再删除缓存:这是相对常用的策略。更新数据库成功后,删除缓存,下次查询时会重新从数据库加载数据到缓存。但如果删除缓存失败,可能会导致数据不一致。可以通过重试机制,多次尝试删除缓存;或者记录删除失败的缓存键,通过异步任务进行补偿处理。
    • 使用消息队列:将数据更新操作发送到消息队列,确保数据库和缓存的更新顺序一致且可靠。消息队列按顺序处理更新消息,先更新数据库,再更新缓存或删除缓存,避免并发更新导致的数据不一致问题。