面试题答案
一键面试解决方案设计
- 读写分离架构:使用MySQL主从复制实现读写分离,主库负责写操作,从库负责读操作,降低主库压力。
- 缓存更新策略:采用“读写锁 + 延迟双删”策略。
- 分布式锁:使用分布式锁(如Redis分布式锁)来保证同一时间只有一个线程能对数据进行写操作,避免并发写导致的数据不一致。
读流程
- 应用程序首先从Redis缓存中读取商品数据。
- 如果Redis中有数据,直接返回给应用程序。
- 如果Redis中没有数据,从MySQL从库中读取数据。
- 将从MySQL读取到的数据写入Redis缓存,并返回给应用程序。
写流程
- 应用程序获取分布式锁。
- 成功获取锁后,更新MySQL主库中的商品数据。
- 先删除Redis缓存中的数据。
- 延迟一段时间(如100ms)后,再次删除Redis缓存中的数据。
- 释放分布式锁。
可能遇到的问题及应对策略
- 缓存穿透:大量请求查询不存在的数据,导致请求直接穿透到MySQL。应对策略:使用布隆过滤器,在查询前先判断数据是否存在,避免无效查询。
- 缓存雪崩:Redis缓存中的大量数据同时过期,导致大量请求直接访问MySQL。应对策略:设置不同的过期时间,避免数据同时过期;使用互斥锁,保证同一时间只有一个请求去更新缓存。
- 缓存击穿:高并发下,一个热点数据在缓存过期的瞬间,大量请求同时访问MySQL。应对策略:使用互斥锁,保证同一时间只有一个请求去查询和更新缓存;或者将热点数据设置为永不过期,定期更新。
- 延迟双删时间设置问题:如果延迟时间过短,可能在第一次删除后,其他线程又重新写入了旧数据到缓存,第二次删除时已经无效。应对策略:根据业务场景和数据更新频率,合理设置延迟时间,可通过压测来确定合适的值。
- 分布式锁失效问题:可能由于网络问题、锁过期等原因导致分布式锁失效。应对策略:设置合理的锁过期时间,并且在获取锁时记录当前线程的标识,在释放锁时进行验证,避免误释放其他线程的锁;可以使用Redisson等更可靠的分布式锁框架。