当前位置:首页 > 前端设计 > 正文

redis雪崩和穿透,redis雪崩怎么解决

redis雪崩和穿透,redis雪崩怎么解决

各位老铁们,大家好,今天由我来为大家分享redis雪崩和穿透,以及redis雪崩怎么解决的相关问题知识,希望对大家有所帮助。如果可以帮助到大家,还望关注收藏下本站,您的...

各位老铁们,大家好,今天由我来为大家分享redis雪崩和穿透,以及redis雪崩怎么解决的相关问题知识,希望对大家有所帮助。如果可以帮助到大家,还望关注收藏下本站,您的支持是我们最大的动力,谢谢大家了哈,下面我们开始吧!

海量数据下如何正确访问Redis服务才不会挂掉

要保证Redis不会挂掉,也就是提高Redis的高可用性,可以从这么几个方面考虑。

集群式部署方式

Redis单副本:也就是只部署一台Redis,不需要节点之间的数据同步,架构简单,部署方便;但是单台机器毕竟是有风险的,按照题目中【海量数据】的场景,是不能达到高可用要求的。

Redis主从:主从实例可以部署在不同的物理服务器上,充分利用多台服务器的资源,在主库发生故障的时候,可以进行主备切换,从而保证系统的稳定运行,甚至可以做到读写分离,主库专门用作写操作,一台或多台备库进行读操作;但是当主库发生故障的时候(如果没有HA方案的话),是需要手动进行主备切换的。

RedisSentinel:部署架构分为两部分【Sentinel集群】和【数据集群】;Sentinel集群是由多个Sentinel节点组成的分布式集群,通常是2N+1台服务器,可以实现故障发现和转移、客户端通知等功能;数据集群用于存储数据;它能够解决主从模式下的自动切换问题,并且数据集群是可以横向扩展的;当然这个架构实现和部署起来,也更为复杂一些;并且这个架构不能做到读写分离。

RedisCluster:Redis3.0集群,是分布式集群解决方案之一,物理架构中配置2N个节点(主从一一对应),主节点提供读写操作,从节点作为备份;数据分布保存在多个节点上,是一种无中心的架构,如果有部分节点发生故障,能够实现故障自动转移和切换,用投票机制完成备库升级为主库(下文的Redis分片章节,还会介绍到RedisCluster)。

Redis分片

Redis在3.0之前只支持单实例,在此之前,在数据量比较大的情况,通常有几种方案可以做到把数据分片保存到多台服务器上。

客户端分片:分片逻辑被放到了客户端上,由客户端根据路由规则,把数据保存不同的Redis实例中,读取的时候也是根据规则,去对应的实例上读取数据;但是当Redis实例数量发生变化的时候(增加实例或减少实例),需要手动地调整分片的规则程序;并且这种部署方式,也增加了运维的成本。

Redis代理组件:在这种架构中,客户端不再直接访问Redis实例,而是访问代理组件,由它管理路由的规则;客户端不需要关心有几个Redis实例,数据被路由到哪个实例上;但是由于在客户端和Redis之间增加了一层代理,多多少少也会产生一些性能上的损耗。

RedisCluster:上文中提到的Redis3.0集群,这里对数据的存储和路由方式,再介绍几句:Redis把所有的Key分成了16384个slot,每个Redis实例负责其中一部分slot;每个Redis都知道每个slot在哪个节点上存储(实例节点定期做数据交换);当客户端访问到一个Redis实例的时候,如果数据不在这个实例上,那么会通过重定向命令引导客户端访问数据所在的实例。

热点数据挑战单节点的极限

虽然我们已经把数据分散保存到多台Redis实例上了,但是如果有一个热点数据被频繁访问,超过了单实例的服务器极限,那么该如何解决呢?通常的手段就是做读写分离,部署多台只读节点,对外提供服务。

我将持续分享Java开发、架构设计、程序员职业发展等方面的见解,希望能得到你的关注。

如何解决Redis缓存雪崩、缓存穿透、缓存并发等问题

缓存穿透

很多项目在使用Redis或其他缓存框架的时候,都是先查询缓存,查询不的话再查询数据库,查到之后再放到内存中;如果一个key值本身就不存在,那么每一次都会查询数据库,也就是常说的【缓存穿透】。

应对方法:

如果在Redis中查询不到,并且查询数据库也没有结果,那么就将这个key写入到Redis中,value=空,并设置一个超时过期时间,例如五分钟,那么五分钟以内的对这个可以的所有查询就可以拦截下来,如果数据库有key对应的数据了,那么五分钟后Redis中的缓存过期,会访问数据库并加载缓存;但是如果被恶意攻击,每次请求的key都不相同且不存在,那么依然会穿透到数据库;

布隆过滤器:将可能存在的数据Hash到一个足够大的bitmap上,它可以告诉你“某个key一定不存在或者可能存在”,一个一定不存在的数据会被bitmap拦截。

缓存雪崩

很多时候,Redis中的缓存是要设置过期时间的,假如Redis中的数据,过期时间都设置成一样的,那么到了时间之后,全部缓存过期失效,下一秒所有的请求都会访问数据库,那么数据库可能因为访问量多大导致“崩溃”,这就是缓存雪崩。

应对方法:

最暴力的解决办法,缓存不设置自动过期时间,只要缓存不崩,数据库就不会崩。

另外一个办法,就是让缓存过期时间不那么一致,比如一批缓存数据24小时后过期,那么就在这个基础上,每条缓存的过期时间前后随机1-6000秒(1-10分钟)。

缓存并发

大多数时候,我们的程序访问Redis都不可能是单线程,那么当多个Client并发对Redis进行setkey操作的时候,可能会产生一些问题;其实Redis本身是单线程的,这种时候会按照先后顺序进行操作;或者把操作放在队列中,按顺序执行;

但比如这种情况:

token过期,有两个线程都去重新获取token;

线程1获取token1;

线程2获取到token2,此时token1过期;

线程1把token1放到Redis,再拿着token1去调用服务,发现过期了,继续去请求token3,此时token2过期;

线程2把token2放到Redis,再拿着token2去调用服务,发现过期了,继续去请求token4,此时token3过期;

......

这就需要我们在更新缓存的时候,做一些控制了。

我将持续分享Java开发、架构设计、程序员职业发展等方面的见解,希望能得到你的关注。

好了,文章到这里就结束啦,如果本次分享的redis雪崩和穿透和redis雪崩怎么解决问题对您有所帮助,还望关注下本站哦!

最新文章