你必须要知道的雪崩穿透预热更新降级

肝铁侠 肝铁侠     2022-12-21     662

关键词:

以前总觉得,写得一手好Java代码,走遍天下都不怕,后来随着时间得推移,才意识到程序的高效性流畅性才是最重要最重要的。 所有的技术都是前人不断实践突破革新留下的产物,它们的存在以及运用一定有它的道理。 于是博主最近将重心向程序的高效性和流畅性的基础学习上偏移了一下,而今天为大家分享的就是Redis在面对小数据量下的大量数据请求的时候,所可能遇到的一些问题。

首先我们要知道什么是Redis,Redis能干嘛?

Redis全称:Remote Dictionary Server,它的字面意思是远程+字典+服务,本质上是一个Key-Value的内存数据库,它把数据缓存在物理内存里,由于直接访问内存,所以速度极快,每秒可处理超过10万+的数据量,是我们已知性能最快的Key-Value形Database。 那么Redis为什么这么快呢?首先他是存内存操作,其次他是单线程操作,避免了频繁的上下文切换,再就是采用了非阻塞I/O多路复用机制。 由于Redis直接访问内存,因此我们可以推断出,内存的配置才是影响Redis性能的瓶颈,正应为受到物理内存的限制,所以不能用作海量数据的高性能读写,所以Redis主要运用在小数据量的高性能读写上,而数据要缓存,带宽也是影响Redis性能的因素之一。Redis最出色的地方就是它的 单个value最大限制是1GB! 不像memcached(分布式高速缓存系统)只能保存1MB的数据。另外,Redis可以对存入的Key-Value设置expire即过期时间,因此可以当作一个功能加强版的memcached。Redis提供了五种数据类型,分别是String、hash、list、set、sorted set。

其次我们来谈谈Redis在实际运用中可能遇到的一些问题。

缓存雪崩:
用通俗的话来讲就是既然Redis可以给存入的Key-Value设置过期时间,那么是不是就会存在设置了相同过期时间的数据,如果这个数据量过大,那么如果在同一时间下,大量的缓存过期,就会导致所有原本应该访问缓存的请求将请求压力全部给到数据库,进而对数据库的CPU和内存造成巨大压力,严重的情况还可能会有宕机的情况发生。
怎么解决呢?这里有一个最简单的方法就是将缓存的失效时间给分散开,但是大部分情况下我们都会选择加锁或者队列(先进先出)的方式来保证不会有大量的线程对数据库进行一次性读写,进而避免当雪崩时大量的并发请求压力落到底层的存储系统上。
缓存穿透:
缓存穿透指的是如果用户请求一条数据,而这条数据数据库中不存在,自然这条数据也不会存在于缓存中,当有一个关于这条数据的查询请求产生时,首先会去缓存中查结果是没有,然后再进入到数据库中查没有,再返回为空,相当于进行了两次无用的查询。像这样的请求,绕过缓存直接查询数据库,就涉及到一个缓存命中率 (缓存命中率=从缓存中读取数据的次数/所有访问数据次数) 的问题。
最简单的解决办法就是只要这个查询结果为空(无论是则很难的为空还是系统故障),我们都将则会个值设置默认值并且存入缓存,但是它的过期时间很短,最高只有五分钟,于是在二次查询的时候,就能获取到值了,从而避免了缓存穿透。
最常见的就是采用布隆过滤器,将所有可能存在的数据哈希到一个足够大的Bitmap(典型的哈希表,Bitmap对于每个元素只能记录1bit信息,如果还想完成额外的功能,只能消耗更大的时间空间来完成了)中去,一定不存在的数据会直接被这个bitMap拦截掉,从而避免了底层存储系统的查询压力。对空间的运用到达了一种极致就是Bitmap和布隆过滤器了。
既然这里提到了布隆过滤器,那我们就简单地聊聊它的原理一级运作方式吧。简单来说就是,在引入了(n+1)个相互独立的哈希函数时,保证在给定的空间、误判率下,去完成元素的判重过程。优点是空间效率和查询时间都远超一般的算法,缺点就是有一定的错误识别率和删除困难。总所周知Hash存在一个hash碰撞的问题,用同一个hash得到的两个URL的值可能会存在相同的情况,为了减少冲突,可以多引入几个Hash,如果通过其中一个Hash值得出某元素不在集合中,那么这个元素就一定不在集合中。只有所有的Hash函数告诉我们该元素存在于集合时,才能确定该元素存在于集合。这就是Bloom-Filter(布隆过滤器)的基本思想,布隆过滤器主要用于在大数据量的集合中去判断某元素是否存在。
缓存预热:
预热相信大家通过字面意思就能理解,好比一个零度的玻璃杯,你突然向里面加入一百度的开水,肯定会对玻璃杯造成偌大的承受压力,所以就得提前预热。预热就是当系统上线以后,将相关的缓存直接加载到缓存系统,这样可以避免用户在发送请求的时候先查询数据库,然后再将数据缓存的问题。这样用户在发送请求的时候就可以访问实现被预热的缓存数据。
缓存预热可以通过写一个定时器去定时刷新缓存,既然涉及到了定时器刷新,那么建议再写一个方法与定时器调用同一个接口,进而可以实现手动刷新。当项目中数据量不大的时候,还可以在项目启动的时候自行加载一下。
缓存更新:
常见的处理策略:①定时去清理过期的缓存。但是维护大量缓存的Key是比较麻烦的。②当一个请求产生时,再去判断这个请求所用到的缓存是否过期,过期的话就去底层系统中得到新数据并更新缓存。这种办法显然每次都去判断,逻辑相对来说要复杂一点。
其实缓存服务器是自带了缓存失效策略的,Redis则提供了定时、定期、惰性删除等过期策略,有六种策略机制:
①volatile-lru:从已设置过期时间的数据集(server.db[i].expires)中挑选最近最少使用的数据淘汰
②volatile-ttl:从已设置过期时间的数据集(server.db[i].expires)中挑选将要过期的数据淘汰
③volatile-random:从已设置过期时间的数据集(server.db[i].expires)中任意选择数据淘汰
④allkeys-lru:从数据集(server.db[i].dict)中挑选最近最少使用的数据淘汰
⑤allkeys-random:从数据集(server.db[i].dict)中任意选择数据淘汰
⑥no-enviction(驱逐):禁止驱逐数据,新写入操作会报错
如果没有一条数据没有设置expire的key,那么这条数据就不满足先决条件,那么volatile-lru、volatile-ttl、volatile-random就默认其为不删除。大家可以到 Redis包中的redis.conf(windows版本的redis叫redis.windows.conf,找.conf文件就对了) 中查看并设置一下自己的缓存策略。

缓存降级:
当访问量剧增,服务器就会受到访问量的影响例如响应时间慢或者不响应的情况,当非核心的服务影响到了核心流程的性能时,我们要保证核心服务仍然是可用的,即使这个操作有损系统服务。它的最终目的就是保证核心服务可用。像购物车、结算等是不可降级的。
以参考日志级别设置预案:
①一般:比如有些服务偶尔因为网络抖动或者服务正在上线而超时,可以自动降级;
②警告:有些服务在一段时间内成功率有波动(如在95~100%之间),可以自动降级或人工降级,并发送告警;
③错误:比如可用率低于90%,或者数据库连接池被打爆了,或者访问量突然猛增到系统能承受的最大阀值,此时可以根据情况自动降级或者人工降级;
④严重错误:比如因为特殊原因数据错误了,此时需要紧急人工降级。服务降级的目的,是为了防止Redis服务故障,导致数据库跟着一起发生雪崩问题。
所以对于一些不重要的缓存数据在程序性能遇到高压的时候可以通过缓存服务降级策略保证主要核心服务仍然可用。

好了,今天的分享就到这里,欢迎大家一起交流学习!

redis缓存穿透击穿雪崩预热更新降级(代码片段)

...会出现在Redis面试题中:缓存穿透、缓存击穿、缓存雪崩、缓存预热、缓存更新、缓存降级。本篇分别介绍这些概念以及对应的解决方案。一、缓存穿透缓存穿透:key对应的数据在数据源并不存在,每次针对此key的请... 查看详情

全面理解redis雪崩击穿穿透预热降级一次全安排(代码片段)

关于Redis的介绍、特点什么的就不再这里赘述了,不然又要水千把字。今天我们就重点看企业中在使用Redis常见一些问题以及对应解决方案。某个请求到达业务系统,想要获取某个数据,一般是先从缓存中获取,如... 查看详情

作为web开发人员,你必须要知道的问题!(持续更新)

GET和POST的区别 GET请注意,查询字符串(名称/值对)是在GET请求的URL中发送的:/test/demo_form.asp?name1=value1&name2=value2GET请求可被缓存GET请求保留在浏览器历史记录中GET请求可被收藏为书签GET请求不应在处理敏感数据时使用GET... 查看详情

redis的缓存穿透缓存雪崩缓存击穿问题的概念与解决办法(代码片段)

详细介绍了Redis的缓存穿透、缓存雪崩、缓存击穿等问题的概念与解决办法。文章目录1缓存穿透1.1什么是缓存穿透?1.2怎么解决1.3BloomFilter布隆过滤器1.3.1BloomFilter的原理1.3.2BloomFilter的优缺点1.3.3GuavaBloomFilter1.3.4RedisBloomFilter2... 查看详情

深入集合类系列——你必须要知道的两棵继承树

查看详情

缓存穿透雪崩

...setNX方法设置一个状态位,表示这是一种锁定状态;缓存雪崩问题将缓存失效时间随机打散设置缓存不过期: 我们可以通过后台服务来更新缓存数据,从而避免因为缓存失效造成的缓存雪崩,也可以在一定程度上避免缓存并... 查看详情

关于程序国际化你必须要知道这事

银弹谷零代码开发平台V百科|新功能:关于国际化你必须要知道这事小张最近有一个烦恼!他们公司最近接了一个跨国合作的项目,小张因为业绩优秀英语功底扎实,也有多年做项目的经验,所以就被领导派去做项目负责人。但... 查看详情

你必须要知道的10款app开发框架

对于大部分Web开发人员,HTML、CSS和Javascript是他们最熟练的开发技能。然而,开发一个原生的移动App,对他们来说却是完全陌生的领域。因为开发Android,iOS或WindowsPhone上的原生App(app开发公司ty300.com),需要掌握完全不同的开发... 查看详情

关于ffmpeg-php你必须要知道的

1#PHPFFmpeg23[![BuildStatus](https://secure.travis-ci.org/PHP-FFMpeg/PHP-FFMpeg.png?branch=master)](http://travis-ci.org/PHP-FFMpeg/PHP-FFMpeg)45[![SensioLabsInsight](https://insight.sensiolabs.com/pr 查看详情

缓存雪崩击穿穿透

   缓存雪崩:   为了保证缓存中的数据与数据库中的数据一致性,会给Redis里的数据设置过期时间,当缓存数据过期后,用户访问的数据如果不在缓存里,业务系统需要重新生成缓存,因此就会访问数据库... 查看详情

关于http协议,你必须要知道的(代码片段)

引言HTTP协议是HyperTextTransferProtocol(超文本传输协议)的缩写,是用于从万维网服务器传输超文本到本地浏览器的传送协议。HTTP是基于TCP/IP协议通信协议来传递数据(HTML文件,图片文件,查询结果等)。它不涉及数据包(packet)传... 查看详情

关于配置,你必须要知道这一点....(代码片段)

kafka管控平台推荐使用滴滴开源的Kafka运维管控平台(戳我呀)更符合国人的操作习惯、更强大的管控能力、更高效的问题定位能力、更便捷的集群运维能力、更专业的资源治理、更友好的运维生态、BliBli视频:石臻臻的杂货铺kafka的... 查看详情

oracle!你必须要知道的knowledgepoints(入门篇)(代码片段)

一、入门oracle有四个用户,分别为sys、system、sysman和scott,其中sys是oracle权限最高的用户,类似于Linux系统的root,scott是实例用户,上课就以这个用户里的三张员工表empno、dept、salgrade作为示例来授课。启动服务1.快捷键ctrl+alt+del打... 查看详情

oracle!你必须要知道的knowledgepoints(下)(代码片段)

子查询什么是子查询当查询中的限制条件需要另一个查询提供时,我们可以把两个查询语句嵌套起来,提供条件的查询语句作为子查询。子查询,也叫内部查询,先于主查询执行,子查询的结果被用于主查询。子查询分为单行子... 查看详情

缓存的雪崩,击穿,穿透

...什么的,常用的缓存有哪些?什么是缓存我们要知道缓存其实就是一个临时的存储器,那么缓存里的数据就不是持久化的数据,只是在我们查询的过程中,来提高我们的效率的东西,那么我们对数据 查看详情

想要节省空间,你必须要知道——动态内存管理(附通讯录动态内存版源码)(代码片段)

想要节省空间,你必须要知道——动态内存管理(附通讯录动态内存版源码)1.    为什么存在动态内存分配2.    动态内存函数的介绍2.1    malloc2.2    freemalloc和free通常配合一起使用:2.3    calloc2.4   ... 查看详情

在做自动化测试之前你必须要知道的事

做测试好几年了,真正学习和实践自动化测试一年,自我感觉这一个年中收获许多。我们更普遍的认识把“自动化测试”看做“基于产品或项目UI层的自动化测试”。 UI层的自动化测试,这个大家应该再熟悉不过... 查看详情

你必须要知道的软件测试3个主流方式

在产品项目的最后推进过程中,会经过一系列的测试来判断以及优化产品,在测试中使产品的属性特征最优化,最终达到吸引更多客户的目的;本文作者分享了三种软件测试的主流方式,我们一起来了解一下... 查看详情