Redis学习总结(10)——缓存雪崩、缓存穿透、缓存并发、缓存预热、缓存更新、缓存降级、缓存算法的概念及解决思路总结

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u012562943/article/details/83110060

前言

缓存是CPU的一部分,它存在于CPU中 CPU存取数据的速度非常的快,一秒钟能够存取、处理十亿条指令和数据(术语:CPU主频1G),而内存就慢很多,快的内存能够达到几十兆就不错了,可见两者的速度差异是多么的大,缓存是为了解决CPU速度和内存速度的速度差异问题。缓存就是数据交换的缓冲区(称作Cache),当某一硬件要读取数据时,会首先从缓存中查找需要的数据,如果找到了则直接执行,找不到的话则从内存中找。由于缓存的运行速度比内存快得多,故缓存的作用就是帮助硬件更快地运行。因为缓存往往使用的是RAM(断电即掉的非永久储存),所以在用完后还是会把文件送到硬盘存储器里永久存储。电脑里最大的缓存就是内存条了,最快的是CPU上镶的L1和L2缓存,显卡的显存是给显卡运算芯片用的缓存,硬盘上也有16M或者32M的缓存。而系统缓存从实践角度上一般分为服务器端缓存,客户端缓存和第三方缓存。而服务器端缓存可分为静态文件缓存和动态缓存,其中动态缓存方式分为传统缓存方式,页面输出缓存,页面输出缓存API,页面局部缓存,应用程序数据缓存,和缓存依赖。第三方缓存如redis,codis,memachae等。

一、缓存雪崩

概念:

可能是因为数据未加载到缓存中,或者缓存同一时间大面积的失效,从而导致所有请求都去查数据库,导致数据库CPU和内存负载过高,甚至宕机。

解决思路:

1.1、加锁计数(即限制并发的数量,可以用semphore)或者起一定数量的队列来避免缓存失效时大量请求并发到数据库。但这种方式会降低吞吐量。

1.2、分析用户行为,然后失效时间均匀分布。或者在失效时间的基础上再加1~5分钟的随机数。

1.3、如果是某台缓存服务器宕机,则考虑做主备。

二、缓存穿透

概念:

指用户查询数据,在数据库没有,自然在缓存中也不会有。这样就导致用户查询的时候,在缓存中找不到,每次都要去数据库中查询。

解决思路:

如果查询数据库也为空,直接设置一个默认值存放到缓存,这样第二次到缓冲中获取就有值了,而不会继续访问数据库。设置一个过期时间或者当有值的时候将缓存中的值替换掉即可。可以给key设置一些格式规则,然后查询之前先过滤掉不符合规则的Key。

三、缓存并发

概念:

如果网站并发访问高,一个缓存如果失效,可能出现多个进程同时查询DB,同时设置缓存的情况,如果并发确实很大,这也可能造成DB压力过大,还有缓存频繁更新的问题。

解决思路:

对缓存查询加锁,如果KEY不存在,就加锁,然后查DB入缓存,然后解锁;其他进程如果发现有锁就等待,然后等解锁后返回数据或者进入DB查询。

四、缓存预热

概念:

目的就是在系统上线前,将数据加载到缓存中。

解决思路:

数据量不大的话,在系统启动的时候直接加载。自己写个简单的缓存预热程序。

五、缓存更新

概念:

缓存数据过期更新和淘汰

解决思路:

除了缓存服务器自带的缓存失效策略之外(Redis默认的有6中策略可供选择),我们还可以根据具体的业务需求进行自定义的缓存淘汰,常见的策略有两种:(1)定时去清理过期的缓存;(2)当有用户请求过来时,再判断这个请求所用到的缓存是否过期,过期的话就去底层系统得到新数据并更新缓存。两者各有优劣,第一种的缺点是维护大量缓存的key是比较麻烦的,第二种的缺点就是每次用户请求过来都要判断缓存失效,逻辑相对比较复杂!具体用哪种方案,可以根据自己的应用场景来权衡。

六、缓存降级

概念:

当访问量剧增、服务出现问题(如响应时间慢或不响应)或非核心服务影响到核心流程的性能时,仍然需要保证服务还是可用的,即使是有损服务。系统可以根据一些关键数据进行自动降级,也可以配置开关实现人工降级。降级的最终目的是保证核心服务可用,即使是有损的。而且有些服务是无法降级的(如加入购物车、结算)。

解决思路:

在进行降级之前要对系统进行梳理,看看系统是不是可以丢卒保帅;从而梳理出哪些必须誓死保护,哪些可降级;比如可以参考日志级别设置预案:(1)一般:比如有些服务偶尔因为网络抖动或者服务正在上线而超时,可以自动降级;(2)警告:有些服务在一段时间内成功率有波动(如在95~100%之间),可以自动降级或人工降级,并发送告警;(3)错误:比如可用率低于90%,或者数据库连接池被打爆了,或者访问量突然猛增到系统能承受的最大阀值,此时可以根据情况自动降级或者人工降级;(4)严重错误:比如因为特殊原因数据错误了,此时需要紧急人工降级。

七、缓存算法

概念:

FIFO算法:First in First out,先进先出。原则:一个数据最先进入缓存中,则应该最早淘汰掉。也就是说,当缓存满的时候,应当把最先进入缓存的数据给淘汰掉。

解决思路:

LFU算法:Least Frequently Used,最不经常使用算法。LRU算法:Least Recently Used,近期最少使用算法。LRU和LFU的区别。LFU算法是根据在一段时间里数据项被使用的次数选择出最少使用的数据项,即根据使用次数的差异来决定。而LRU是根据使用时间的差异来决定的。

没有更多推荐了,返回首页