面试题答案
一键面试缓存穿透
- 原因:
- 客户端持续请求一个在数据库和缓存中都不存在的数据,导致请求直接穿透缓存到达数据库,对数据库造成压力。比如恶意用户频繁请求不存在的商品ID。
- 解决方案及优缺点:
- 布隆过滤器:
- 优点:空间效率高,能以极小的空间存储大量数据的映射,快速判断一个数据是否存在,有效拦截大量不存在的数据请求,防止穿透到数据库。
- 缺点:存在误判率,即可能会误判某个数据存在,不过误判率可以通过调整布隆过滤器的参数(如哈希函数个数、位数组大小等)来控制。同时,新增数据时需要重新计算布隆过滤器。
- 缓存空值:
- 优点:实现简单,在查询数据库未找到数据时,将空值也缓存起来,并设置较短的过期时间。下次相同请求直接从缓存获取空值,避免穿透到数据库。
- 缺点:会额外占用缓存空间,且如果空值缓存时间设置不合理,可能导致数据更新不及时,比如数据在数据库中新增了,但由于空值缓存未过期,仍无法查询到新数据。
- 布隆过滤器:
缓存雪崩
- 原因:
- 大量缓存数据在同一时间过期,导致大量请求直接涌向数据库,造成数据库压力过大甚至崩溃。比如缓存的一批商品数据设置了相同的过期时间,到期后同时失效。
- 解决方案及优缺点:
- 设置随机过期时间:
- 优点:简单有效,将缓存数据的过期时间设置为一个随机值,在一定范围内波动,避免大量数据同时过期。
- 缺点:无法精确控制过期时间,如果随机范围设置不合理,可能仍然会有部分数据集中过期。同时,对于一些需要精确控制过期时间的场景不太适用。
- 加锁排队:
- 优点:当缓存失效时,通过加锁(如Redis的SETNX操作)让一个请求去查询数据库并更新缓存,其他请求等待,从而避免大量请求同时访问数据库。
- 缺点:加锁会降低系统的并发性能,排队等待会增加请求的响应时间。如果锁的释放逻辑有问题,可能导致死锁,影响系统正常运行。
- 设置随机过期时间:
缓存击穿
- 原因:
- 对于某个热点数据,其缓存过期的瞬间,大量请求同时访问,导致这些请求绕过缓存直接访问数据库,对数据库造成巨大压力。比如某个热门商品的缓存过期时,大量用户同时抢购该商品。
- 解决方案及优缺点:
- 使用互斥锁:
- 优点:与缓存雪崩中加锁排队类似,在缓存过期时,通过互斥锁保证只有一个请求去查询数据库并更新缓存,其他请求等待。可以有效防止大量请求同时穿透到数据库。
- 缺点:同样会降低系统并发性能,增加请求响应时间,且存在死锁风险。如果锁的粒度控制不好,可能影响其他相关业务操作。
- 永不过期:
- 优点:对于热点数据,设置为永不过期,同时在数据更新时主动更新缓存。这样可以避免因缓存过期导致的击穿问题。
- 缺点:数据可能长时间不更新,导致数据不一致。而且如果不及时主动更新缓存,可能会影响业务的正确性。同时,对于需要按一定周期失效的数据场景不适用。
- 使用互斥锁: