Redis缓存雪崩、缓存穿透、缓存预热、缓存倾斜、缓存穿刺击穿、缓存更新、缓存降级解决方案

Redis缓存雪崩、缓存穿透、缓存预热、缓存倾斜、缓存穿刺击穿、缓存更新、缓存降级 等解决方案

-雪崩
缓存中大量数据短时间到期,然后短时间内不同人在访问这些数据,导致高并发(穿刺是某一条数据的高并发,雪崩是很多不同数据最终高并发,当然雪崩也有可能包含穿刺的数据)访问数据库

解决:

​ 1.设置不同的到期时间,将缓存的失效时间分散开,这样每一个缓存的过期时间的重复率就会降低,就很难引发大量的缓存集体性失效的事件。

​ 2.大多数系统设计者考虑:用加锁或者队列的方式,来保证同一时间内不会有大量的线程,同时对数据库进行读写,从而避免 数据库崩溃掉。
-穿透
查询数据库中不存在的数据,因为数据库中不存在,所以缓存中肯定没有,所有的请求都会落在数据库上面,若高并发的话,数据库就奔溃了

解决

​ 1.我们一般都是主键查询,其他查询走搜索,主键如果是自增的,可将当前数据库的主键最大值放缓存,然后修改流程为先查询缓存,有的话返回,没有的话先比较查询的主键和缓存中放的最大值,小于等于最大值就代表在数据库中然后继续流程

​ 2.若主键不是自增的,就将所有的主键提出来放入redis的set中,然后上面的流程改为先查询缓存,有的话则返回,没有的话先判断查询的主键在不在set中,在就查询数据库,不在返回

​ 3.采用布隆过滤器,将所有可能存在的数据哈希到一个足够大的bitmap中,一个一定不存在的数据会被这个bitmap拦截掉,从而避免了对数据库的查询压力。

​ 4.如果一个查询返回的数据为空,我们仍然把这个空结果进行缓存,这样用户请求第二次到缓冲中获取就有值了,而不会继续访问数据库,这种办法最简单粗暴!
-击穿/穿刺
缓存中某一条热点数据因某些原因失效了或者不见了,若此时高并发访问这个数据,根据上面的防穿透原则,发现这数据在数据库中,此时会有不少高并发去查询数据库,因为查询到数据并放入缓存中需要时间,在此时间内可能会有不少并发,照成数据库压力倍增,可能会奔溃

解决:

​ 1.既然查询的都是相同数据,就没必要都去查询,只要有一个去查询数据库,并放入缓存,其他人在从缓存中去取就可以,所以从数据库查询的地方加分布式锁****/在请求访问key之前,采用SETNX来设置一个短期key,锁住当前key的访问,访问结束再删除该短期key/,拿到锁的人去查库,拿到后放入缓存,那不到的人等待唤醒,唤醒后从缓存中去取就可以,这样不管是高并发还是低并发的穿刺,都会被解决,当然数据丢失的问题,也要根据具体原因去解决

​ 2.设置这个热点数据永不过期;
-倾斜
​ 缓存倾斜又称为:热点key倾斜。我们的redis一般都是集群,然后每个key更具(一致性hash算法)会落到某个集群的主机上面,如果出现了搞热数据,比如像某某微博的热点新闻,他们的key是固定的,所以这个key一定是在某个服务器上的,这个时候,如果高并发的话,大量的请求会涌向集群中的某一台服务器上,而我们使用集群的目的就是要平分请求,现在大量的请求集中到某台服务器上导致了倾斜,甚至可能导致缓存服务器的崩溃

​ 解决:

​ 产生的原因大量请求去了一个机器,那我们只要让他去不同的机器就行,利用redis的日活统计,判断是否要增加key到不同的机器上。

​ 1.我们的redis某个主机下面肯定有从机,所以我们可以做读写分离数据查询,分配到不同的从机上面,所以只需要做一个注册中心,里面放对应的从机列表,应用服务气在查询数据的时候,先获取从机列表,在从里面查

​ 2.我们将数据放到不同的主机上,因为相同的key一定在某个机器上,所以可以将这个数据存几个不同的key,比如程序员,原始key是666cxy,那就可以放成666cxy:1,666cxy:2。。。。,不同的key放的数据一样,然后利用不同的key,放到不同的服务器上面,这个特点来平分请求,那取得时候哪个key呢,我们可以给应用服务器加标记,比如第一个机器是1,第二个是2,以此类推,应用服务取数据之前,发现这个数据是热点数据,那么根据key加上自己的标记,然后根据这个key去取数据,查询的时候使用hash取模算法,将压力分摊到不同的节点。

​ 3.将一些特别热点的key直接放在客户端进行存储,设置过期时间,过期后再从后台中查询。

​ 缓存倾斜的出现场景,在解决缓存穿透和缓存穿刺的时候也可能会出现倾斜问题,其中穿刺和倾斜本身就很像,不过倾斜是从数据库加载到缓存之后,(也就是在解决穿刺用锁限制一个和连接加载数据之后剩下的请求)可能会发生,但是解决缓存穿透的方式也可能会导致倾斜问题,原因是高并发的时候,如果缓存中大量数据不存在,都去redis中判断key在不在的时候,就会高并发访问这个存放有主键的key了,那么这个key就倾斜了。

预热

​ 缓存预热就是系统上线之后,将一些缓存数据先加载到缓存系统中。这样就可以避免在用户请求的时候,先查询数据库,然后再将数据缓存的问题! 用户直接查询事先被预热好的缓存数据!

解决:

除了缓存服务器自带的缓存失效策略之外,我们还可以根据具体的业务需求,进行自定义的缓存淘汰。

​ 1.定时去清理过期的缓存;

​ 2.当有用户请求过来时,先判断这个请求所用到的缓存是否过期,过期的话就去数据库中得到新数据,同时并更新到缓存中。
-缓存降级/服务降级
当访问量剧增、服务出现问题时,仍然需要保证核心的服务还是可用的,这时可以采用关闭一些非核心的服务的方式,来保证核心服务可用。即,丢卒保帅。 降级的最终目的是保证核心服务可用。

你可能感兴趣的:(Redis)