面试题答案
一键面试缓存穿透
- 产生原因:
- 客户端请求的数据在缓存和数据库中都不存在,每次请求都会穿透缓存直接查询数据库。例如,恶意用户故意请求不存在的键,大量这样的请求会使数据库压力剧增。
- 预防和解决手段:
- 布隆过滤器:在缓存之前使用布隆过滤器。布隆过滤器可以快速判断某个数据一定不存在或者可能存在。当请求到达时,先经过布隆过滤器,如果布隆过滤器判断数据不存在,则直接返回,不再查询数据库。这样可以有效拦截大量不存在数据的请求。
- 空值缓存:当数据库查询结果为空时,也将空值缓存起来,并设置较短的过期时间。下次相同请求过来时,直接从缓存获取空值,避免查询数据库。
缓存雪崩
- 产生原因:
- 大量缓存数据在同一时间过期,导致后续大量请求直接访问数据库,使数据库压力瞬间增大,甚至可能导致数据库崩溃。例如,在电商大促后,大量商品的缓存同时过期,后续用户请求就会直接冲击数据库。
- 预防和解决手段:
- 设置随机过期时间:避免所有缓存数据设置相同的过期时间,而是在一个合理的时间范围内设置随机的过期时间,使缓存过期时间分散开,降低大量缓存同时过期的风险。
- 缓存预热:在系统启动时,提前将部分热点数据加载到缓存中,避免在系统上线初期大量请求直接访问数据库。
- 使用二级缓存:可以采用主从缓存或者多级缓存的方式,当一级缓存失效时,二级缓存可以继续提供服务,减少对数据库的冲击。同时对二级缓存也设置合理的过期时间。
- 搭建高可用缓存集群:使用如Redis Cluster等方式搭建高可用的缓存集群,当部分缓存节点失效时,其他节点可以继续提供服务,保证缓存整体的可用性。
缓存击穿
- 产生原因:
- 单个热点数据的缓存过期瞬间,大量针对该数据的请求同时到来,这些请求会绕过缓存直接访问数据库,对数据库造成巨大压力。例如,在抢购活动中,某个热门商品的缓存过期,大量抢购请求会直接访问数据库查询商品库存等信息。
- 预防和解决手段:
- 互斥锁:在缓存过期时,使用互斥锁(如Redis的SETNX命令)来保证只有一个请求能查询数据库并更新缓存,其他请求等待。当获取锁的请求更新完缓存后,释放锁,其他请求再从缓存获取数据。这样可以避免大量请求同时查询数据库。
- 热点数据永不过期:对于热点数据,不设置过期时间,同时在数据发生变化时主动更新缓存。这样可以确保热点数据始终在缓存中,不会出现缓存过期导致的击穿问题。
- 使用二级缓存:和缓存雪崩类似,采用二级缓存,一级缓存失效时,二级缓存兜底,减少直接访问数据库的请求数量。