一.缓存雪崩
介绍:同一时间有大量的缓存key同时失效,或者redis服务宕机,导致大量请求到达数据库,给数据库带来巨大压力。
解决方案:
1.给不同的key的过期时间设置随机值,防止大量key同时过期;
2.利用redis集群提高服务可用性,利用哨兵机制实现服务的监控,当有服务宕机,哨兵从其他集群中选一个替代者;
3.给业务添加多级缓存。在nginx中添加缓存,在redis加缓存,在jvm加缓存,最后去数据库查询。
4.给缓存添加降级限流策略,当redis有故障时,实现容错处理,拒绝服务而不是把请求全部压到数据库,牺牲部分服务来保全数据库;
二.缓存击穿
介绍:热点key问题,一个被高并发访问并且重建业务复杂的key突然失效,无数的请求在一瞬间给数据库带来巨大压力。
解决方案:
1.互斥锁:当一个线程进行读写时,其他线程都在等待,等待后拿到的数据为最新数据。
优点:没有额外的内存开销,保证了一致性,实现简单。
缺点:在加锁的线程完成写入缓存前,其他线程一直等待,性能受到影响,可能出现死锁。
2.逻辑过期:用旧数据返回。
优点:线程无序等待,性能好。
缺点:由于会用旧数据,所以不保证一致性,同时要存储过期时间,因此有额外的内存消耗。
三.缓存穿透
介绍:用户请求的数据在redis和数据库中都不存在,不断发起请求给数据库带来巨大压力。
解决方案:
1.缓存null值:当在redis和数据库中都查询不到值时,在缓存中放入空值null,再设置短暂的过期时间,来比秒额外的内存消耗。
优点:实现简单,维护方便。
缺点:额外的内存消耗。
2.布隆过滤:在客户端和redis中间加入过滤器,过滤器可以判断是否存在对象,不存在则直接拒绝,否则正常操作。
优点:内存占用少,没有多余key。
缺点:实现复杂,存在误判可能。
3.增加id的复杂度并做好数据格式校验,避免被恶意查询id。
4.加强用户权限的校验,登录后才能访问。
5.做好热点key的限流,限制用户的访问频率。