Java相关面试都会问缓存问题:缓存雪崩、缓存穿透、缓存预热、缓存更新、缓存降级等.问题,却是一个很重要的问题,今天就来聊聊这个话题。基本看完这篇文章,就可以对redis有一个比较全面的初步了解。后面会加上redis相关的实战文章,总结为一个redis系列。01.缓存雪崩数据没有加载到缓存中,或者大面积的缓存同时失效,导致所有请求都去查数据库,导致数据库CPU和内存负载过高,甚至宕机。比如雪崩的一个简单过程:1.redis集群大面积失效。2、缓存失效,但仍有大量请求访问缓存服务redis。3、大量redis故障后,大量请求转向mysql数据库。5、由于大量应用服务依赖mysql和redis服务,这个时候很快就会演变成服务器集群雪崩,***网站将彻底崩溃。02.缓存雪崩解决方案1.缓存高可用缓存层设计高可用,防止缓存大规模失效。即使个别节点、个别机器甚至机房宕机,仍然可以提供服务。比如RedisSentinel和RedisCluster都实现了高可用。2、缓存降级可以使用本地缓存如ehcache(临时用),但主要需要限流、资源隔离(熔断)、源服务访问降级。当访问量激增,服务出现问题时,仍然需要保证服务仍然可用。系统可以根据一些关键数据自动降级,也可以配置开关实现手动降级,这涉及到运维的配合。降级的最终目标是保持核心服务可用,即使有损。比如我的淘宝页面,因为是非核心页面,如果后台服务暂时不能使用,可以考虑直接换成静态页面,这样就一直为用户提供服务(告警信息将再次发送,提示需要紧急解决),不会出现空白或异常裸奔状态。降级前需要对系统进行梳理,比如:哪些业务是核心(必须保证),哪些业务可以暂时不提供服务(使用静态页面替换)等,配合服务器后期设置整体方案的核心指标,如:(1)General:比如有些服务偶尔会因为网络抖动超时或者服务正在上线,可以自动降级;(2)警告:部分服务成功率在一段时间内波动(如95~100%之间),可自动降级或手动降级,并发出告警;(3)错误:比如可用率低于90%,或者数据库连接池爆掉,或者流量突然飙升到系统可以承受的最大阈值,这时候可以自动降级或根据情况手动;(4)严重错误:比如由于特殊原因导致数据错误,此时需要紧急手动降级。3.Redis备份与快速预热1)Redis数据备份与恢复2)快速缓存预热3).提前演练***,建议在项目上线前先练习缓存层宕机后应用和后端的负载以及可能出现的问题,提前预览高可用,提前发现问题。03.缓存穿透缓存穿透是指查询不存在的数据。例如:如果从缓存redis中没有***,则需要从mysql数据库中查询。如果找不到数据,则不会写入缓存。这样会导致每次请求时都去数据库中查询不存在的数据,造成缓存穿透。解决方法:如果查询数据库也是空的,直接设置一个默认值存入缓存,这样第二次就从缓存中获取该值,而不用继续访问数据库。设置一个过期时间或者有值时替换缓存中的值。可以为key设置一些格式规则,然后在查询前过滤掉不符合规则的key。04.缓存并发这里的并发是指多个redis客户端同时设置key导致的并发问题。其实redis本身就是单线程运行的。多个客户端同时运行。按照先来先执行的原则,先来先执行,其余的都阻塞。当然还有一种方案就是把redis.set操作放到队列中序列化,一个一个执行。05.缓存预热缓存预热是在系统上线后,将相关的缓存数据直接加载到缓存系统中。这样就可以避免用户请求时先查询数据库再缓存数据的问题,用户直接查询提前预热好的缓存数据。解决思路:1、直接写一个缓存刷新页面,上线时手动操作。2、数据量不大,可以在项目启动时自动加载。目的是在系统上线前将数据加载到缓存中。
