面试题答案
一键面试可能遇到的问题
- 缓存更新不及时:MySQL数据更新后,Redis缓存未及时同步更新,导致客户端读取到旧数据。
- 缓存与数据库双写不一致:在高并发场景下,对MySQL和Redis同时进行写操作时,可能出现部分操作成功,部分操作失败,从而导致数据不一致。
- 缓存雪崩:大量缓存同时过期,导致大量请求直接落到MySQL数据库上,可能使数据库压力过大甚至崩溃。
- 缓存穿透:查询不存在的数据时,每次都绕过缓存直接查询数据库,增加数据库压力。
- 缓存击穿:一个存在的热点数据在缓存过期的瞬间,大量请求同时访问,导致这些请求全部落到数据库上。
对应的解决方案
- 缓存更新不及时
- 读写时更新缓存:在对MySQL数据进行写操作(增、删、改)时,立即更新Redis缓存。
- 使用消息队列:将数据变更操作发送到消息队列,由消息队列异步更新Redis缓存,确保数据一致性的同时提高系统的并发性能。
- 缓存与数据库双写不一致
- 重试机制:如果写缓存或写数据库失败,进行重试,直到操作成功。
- 事务机制:使用分布式事务框架(如Seata)来保证对MySQL和Redis的操作要么都成功,要么都失败。
- 缓存雪崩
- 设置不同的过期时间:对缓存数据设置随机的过期时间,避免大量缓存同时过期。
- 使用二级缓存:在一级缓存失效时,从二级缓存获取数据,减轻数据库压力。
- 搭建高可用缓存集群:如使用Redis Sentinel或Redis Cluster,确保缓存服务的高可用性。
- 缓存穿透
- 布隆过滤器:在查询数据前,先通过布隆过滤器判断数据是否存在,不存在则直接返回,避免查询数据库。
- 缓存空值:查询数据库后,如果数据不存在,将空值缓存起来,并设置较短的过期时间。
- 缓存击穿
- 互斥锁:在缓存过期时,使用互斥锁(如Redis的SETNX命令)保证只有一个请求能查询数据库并更新缓存,其他请求等待。
- 热点数据不过期:对热点数据不设置过期时间,由后台线程定时更新缓存数据。