前言
Redis作为一个高性能的内存中的key-value数据结构存储系统,在我们平常开发中广泛利用于缓存、计数器、消息队列、排行榜等场景中,特别是作为最经常使用的缓存方式,在提高数据查询效力、保护数据库等方面起到了不可磨灭的作用,但实际利用中,可能会出现一些Redis缓存异常的情况,本文主要对Redis缓存异常及处理方案进行了总结。
一、背景
Redis是一个完全开源的、遵照BSD协议的、高性能的key-value数据结构存储系统,它支持数据的持久化,可以将内存中的数据保存在磁盘中,而且不单单支持简单的key-value类型的数据,同时还提供list,set,zset,hash等数据结构的存储,功能十分强大,Redis还支持数据的备份,即master-slave模式的数据备份,从而提高可用性。固然最重要的或者读写速度不错,作为我们平常开发中最经常使用的缓存方案被广泛利用。但在实际利用进程中,它会存在缓存雪崩、缓存击穿和缓存穿透等异常情况,如果忽视这些情况可能会带来灾害性的后果,下面主要对这些缓存异常和常见处理方案进行相应分析与总结。
二、缓存雪崩
(一)是甚么
一段时间内本应在redis缓存中处理的大量要求,都发送到了数据库进行处理,致使对数据库的压力迅速增大,严重时乃至可能致使数据库崩溃,从而致使全部系统崩溃,就像雪崩一样,引发连锁效应,所以叫缓存雪崩。
(二)为何
出现上述情况的常见缘由主要有以下两点:
- 大量缓存数据同时过期,致使本应要求到缓存的需重新从数据库中获得数据。
- redis本身出现故障,没法处理要求,那自然会再要求到数据库那里。
(三)怎样办
针对大量缓存数据同时过期的情况:
- 实际设置过期时间时,应当尽可能避免大量key同时过期的场景,如果真的有,那就通过随机、微调、均匀设置等方式设置过期时间,从而避免同一时间过期。
- 添加互斥锁,使得构建缓存的操作不会在同一时间进行。
- 双key策略,主key是原始缓存,备key为拷贝缓存,主key失效时,可以访问备key,主key缓存失效时间设置为短时间,备key设置为长时间。
- 后台更新缓存策略,采取定时任务或消息队列的方式进行redis缓存更新或移除等。
针对redis本身出现故障的情况:
- 在预防层面,可以通过主从节点的方式构建高可用的集群,也就是实现主Redis实例挂掉后,能有其他从库快速切换为主库,继续提供服务。
- 如果事情已产生了,那就要为了避免数据库被大量的要求弄崩溃,可以采取服务熔断或要求限流的方法。固然服务熔断相对粗鲁一些,停止服务直到redis服务恢复,要求限流相对温和一些,保证一些要求可以处理,不是一刀切,不过或者看具体业务情况选择适合的处理方案。
三、缓存击穿
(一)是甚么
缓存击穿一般出现在高并发系统中,是大量并发用户同时要求到缓存中没有但数据库中有的数据,也就是同时读缓存没读到数据,又同时去数据库去取数据,引发数据库压力瞬间增大。和缓存雪崩区别的是,缓存击穿指并发查同一条数据,缓存雪崩是区别数据都过期了,很多数据都查不到从而查数据库。
(二)为何
这类情况其实一般出现的缘由就是某个热门数据缓存过期,由因而热门数据,要求并发量又大,所以过期的时候或者会有大量要求同时过来,来不及更新缓存就全部打到数据库那边了。
(三)怎样办
针对这类情况有两种常见的处理方案:
- 简单粗鲁的对热门数据不设置过期时间,这样不会过期,自然也就不会出现上述情况了,如果后续想清算,可以通过后台进行清算。
- 添加互斥锁,即当过期以后,除要求过来的第一个查询的要求可以获得到锁要求到数据库,并再次更新到缓存中,其他的会被阻塞住,直到锁被释放,同时新的缓存也被更新上去了,后续要求又会要求到缓存上,这样就不会出现缓存击穿了。
四、缓存穿透
(一)是甚么
缓存穿透是指数据既不在redis中,也不在数据库中,这样就致使每次要求过来的时候,在缓存中找不到对应key以后,每次都还要去数据库再查询一遍,发现数据库也没有,相当于进行了两次无用的查询。这样要求就能够绕过缓存直接查数据库,如果这个时候有人想歹意攻击系统,就能够故意使用空值或其他不存在的值进行频繁要求,那末就会对数据库造成比较大的压力。
(二)为何
这类现象的缘由其实很好理解,业务逻辑里面如果用户对某些信息还没有进行相应的操作或处理,那对应的寄存信息的数据库或缓存中自然也就没有相应的数据,也就容易出现上述问题。
(三)怎样办
针对缓存穿透,一般有以下三种处理方案:
- 非法要求的限制,主要是指参数校验、鉴权校验等,从而一开始就把大量的非法要求拦截在外,这在实际业务开发中是必要的手段。
- 缓存空值或默许值,如果从缓存取不到的数据,在数据库中也没有取到,那我们依然把这个空结果进行缓存,同时设置一个较短的过期时间。通过这个设置的默许值寄存到缓存,这样第二次到缓存中获得就有值了,而不会继续访问数据库,可以避免有大量歹意要求是反复用同一个key进行攻击。
- 使用布隆过滤器快速判断数据会不会存在。那甚么是布隆过滤器呢,简单来讲,就是可以引入了多个相互独立的哈希函数,保证在给定的空间和误判率下,完成元素判重。由于我们知道,存在hash碰撞这样一种情况,那如果只使用一个hash函数,则碰撞冲突的几率明显会变大,那为了减少这类冲突,我们可以多引入几个hash函数,而布隆过滤器算法的核心思想就是利用多个区别的hash函数来解决这样一种冲突。它的优点是空间效力高,查询时间短,远超其他算法,而它的缺点就是会存在一定的误辨认率,它不能完全保证要求过来的key,通过布隆过滤器的校验,就一定有这个数据,毕竟理论上或者会存在冲突情况,不管几率多小。但是,只要没有通过布隆过滤器的校验,那末这个key就一定不存在,只要利用这一点其实就已可以过滤掉大部份不存在的key的要求了,在正常场景下已然足够了。
五、其他
除上述三种常见的Redis缓存异常问题以外,还常常听到的有缓存预热和缓存降级两个名词,与其说是异常问题,不如说是两种的优化处理方法。
(一)缓存预热
缓存预热就是系统上线前后,将相关的缓存数据直接加载到缓存系统中去,而不依赖用户。这样就能够避免在用户要求的时候,先查询数据库,然后再将数据缓存的问题。用户直接查询事前被预热的缓存数据,这样可以免那末系统上线早期,对高并发的流量,都会访问到数据库中, 对数据库造成流量的压力。
根据数据区别量级,可以有以下几种做法:
- 数据量不大:项目启动的时候自动进行加载。
- 数据量较大:后台定时刷新缓存。
- 数据量极大:只针对热门数据进行预加载缓存操作。
(二)缓存降级
缓存降级是指当缓存失效或缓存服务出现问题时,为了避免缓存服务故障,致使数据库随着一起产生雪崩问题,所以也不去访问数据库,但由于一些缘由,依然想要保证服务或者基本可用的,虽然肯定会是有损服务。因此,对不重要的缓存数据,我们可以采取服务降级策略。
一般做法有以下两种:
- 直接访问内存部份的数据缓存。
- 直接返回系统设置的默许值。
六、总结
本文主要对常见的Redis缓存异常及其处理方案进行了总结,可以用下图做个概括:
到此这篇关于Redis缓存三大异常的处理方案梳理总结的文章就介绍到这了,更多相关Redis缓存异常内容请搜索之前的文章或继续浏览下面的相关文章希望大家以后多多支持!
文章来源:丸子建站
文章标题:Redis缓存异常的处理方案详解总结
https://www.wanzijz.com/view/72187.html