缓存击穿:
和缓存雪崩相似,雪崩是大面积的数据失效,而缓存击穿是由某一个热点数据key在不停的发生压力,在key失效时候,承受高并发的巨大压力,击穿缓存,进入数据库进行重大打击。
处理方法:
- 设置某个热点数据永不过期或者设置多个热点数据失效时间随机即可。
- 使用互斥锁更新,保证同一个进程中针对同一个数据不会并发请求到 DB,减小 DB 压力。
缓存穿透:
是指我们的缓存和数据库都没有的数据,而用户还在不断的进行发送请求。
数据库的id一般从1开始自增的。如果进行id为-1或者很大的不存在的数据时,产生数据的压力很大。严重使数据库崩溃。
处理方法:
- 就是每次进行数据请求进行一个拦截处理,参数校验,不符合条件直接不处理。可以在接口层进行用户权限,参数等等的校验或者不合法直接拦截。使用布隆过滤器进程拦截。
- 使用一个空对象进行标记,防止相同的ID进行访问,不好的是就是可能会有很多无用的数据。
缓存雪崩:
通俗的说就是数据库服务器顶不住一次性的大量数据的涌入,而且此时的缓存数据又都失效了,且没有方法处理而进行服务器重启然而又被新的流量打死的情况。没有缓存数据进行一次格挡。
处理方法
- 就是缓存存数据的时候设置每个键(key)的失效时间为随机,可以保证大面积的数据不会再一次性的失效;
- 设置一些热点数据为永不失效,在更新的时候更新缓存就行。
- 使用主从模式和集群模式来尽量保证缓存服务的高可用(实现Redis的高可用(主从架构+Sentinel 或者Redis Cluster))。
- 使用快速失败的熔断策略,减少 DB 瞬间压力。
事发前:实现Redis的高可用(主从架构+Sentinel 或者Redis Cluster),尽量避免Redis挂掉这种情况发生。
事发中:万一Redis真的挂了,我们可以设置本地缓存(ehcache)+限流(hystrix),尽量避免我们的数据库被干掉(起码能保证我们的服务还是能正常工作的)
事发后:redis持久化,重启后自动从磁盘上加载数据,快速恢复缓存数据。
数据库是不会死的,限流组件确保每秒处理多少数据,相当于滑动窗口的设置,限制数据量的传输。基本上五分之三的数据都是会处理的。对于用户来说只是刷新页面的问题。
使用降级牺牲用户的体验而换取服务器的安全。