面试题答案
一键面试可能遇到的场景及解决方案
- 写操作场景
- 先写MySQL,再写Redis
- 问题:写MySQL成功,但写Redis失败,导致数据不一致。
- 解决方案:采用重试机制,对写Redis失败的操作进行重试。可以设置重试次数和重试间隔,若多次重试仍失败,可记录日志,进行人工干预。同时,可引入消息队列,将写Redis失败的操作放入队列,由专门的消费者进行处理,保证最终一致性。
- 先写Redis,再写MySQL
- 问题:写Redis成功,写MySQL失败,导致数据不一致。此时若有读操作,会读到Redis中的旧数据。
- 解决方案:同样采用重试机制处理写MySQL失败的情况。另外,引入事务机制,若写MySQL失败,回滚Redis的写操作。还可以使用分布式事务框架,如Seata等,来保证操作的原子性。
- 先写MySQL,再写Redis
- 读操作场景
- 缓存穿透
- 问题:查询一个一定不存在的数据,由于缓存中没有,每次都会去查询数据库,若大量这样的请求,会给数据库带来巨大压力。
- 解决方案:布隆过滤器(Bloom Filter),在查询前先通过布隆过滤器判断数据是否存在,若不存在直接返回,不再查询数据库。另外,对查询结果为空的情况也进行缓存,设置较短的过期时间,避免持续穿透。
- 缓存雪崩
- 问题:大量缓存同时过期,导致大量请求直接打到数据库,造成数据库压力过大甚至宕机。
- 解决方案:给缓存设置随机过期时间,避免大量缓存同时过期。同时,使用互斥锁,当一个请求发现缓存过期时,获取互斥锁去查询数据库并更新缓存,其他请求等待,避免大量请求同时查询数据库。
- 缓存击穿
- 问题:一个热点数据过期瞬间,大量请求同时查询该数据,直接打到数据库,可能使数据库压力瞬间增大。
- 解决方案:和缓存雪崩类似,使用互斥锁,在热点数据过期时,只有一个请求能获取锁去查询数据库并更新缓存,其他请求等待。也可以对热点数据设置永不过期,定期更新缓存数据。
- 缓存穿透