hystrix完成对redis访问的资源隔离

相对来说,考虑的比较完善的一套方案,分为事前,事中,事后三个层次去思考怎么来应对缓存雪崩的场景

1、事前解决方案

发生缓存雪崩之前,事情之前,怎么去避免redis彻底挂掉

redis本身的高可用性,复制,主从架构,操作主节点,读写,数据同步到从节点,一旦主节点挂掉,从节点跟上

双机房部署,一套redis cluster,部分机器在一个机房,另一部分机器在另外一个机房

还有一种部署方式,两套redis cluster,两套redis cluster之间做一个数据的同步,redis集群是可以搭建成树状的结构的

一旦说单个机房出了故障,至少说另外一个机房还能有些redis实例提供服务

2、事中解决方案

redis cluster已经彻底崩溃了,已经开始大量的访问无法访问到redis了

(1)ehcache本地缓存

所做的多级缓存架构的作用上了,ehcache的缓存,应对零散的redis中数据被清除掉的现象,另外一个主要是预防redis彻底崩溃

多台机器上部署的缓存服务实例的内存中,还有一套ehcache的缓存

ehcache的缓存还能支撑一阵

(2)对redis访问的资源隔离

(3)对源服务访问的限流以及资源隔离

3、事后解决方案

(1)redis数据可以恢复,做了备份,redis数据备份和恢复,redis重新启动起来

(2)redis数据彻底丢失了,或者数据过旧,快速缓存预热,redis重新启动起来

redis对外提供服务

缓存服务里,熔断策略,自动可以恢复,half-open,发现redis可以访问了,自动恢复了,自动就继续去访问redis了

基于hystrix的高可用服务这块技术之后,先讲解缓存服务如何设计成高可用的架构

缓存架构应对高并发下的缓存雪崩的解决方案,基于hystrix去做缓存服务的保护

 

redis集群崩溃的时候,会怎么样?

(1)首先大量的等待,超时,报错
(2)如果是短时间内报错,会直接走fallback降级,直接返回null
(3)超时控制,你应该判断说redis访问超过了多长时间,就直接给timeout掉了

不推荐说用默认的值,一般不太精准,redis的访问你首先自己先统计一下访问时长的百分比,hystrix dashboard,TP90 TP95 TP99

一般来说,redis访问,假设说TP99在100ms,那么此时,你的timeout稍微多给一些,100ms。

1、timeout超时控制

HystrixCommandProperties.Setter()
.withExecutionTimeoutInMilliseconds(int value)

意义在于哪里,一旦说redis出现了大面积的故障,此时肯定是访问的时候大量的超过100ms,大量的在等待和超时

就可以确保说,大量的请求不会卡住过长的时间,比如说卡住个1s,500ms,100ms直接就报timeout,走fallback降级了

2、熔断策略

(1)circuitBreaker.requestVolumeThreshold

设置一个rolling window,滑动窗口中,最少要有多少个请求时,才触发开启短路

举例来说,如果设置为20(默认值),那么在一个10秒的滑动窗口内,如果只有19个请求,即使这19个请求都是异常的,也是不会触发开启短路器的

HystrixCommandProperties.Setter()
.withCircuitBreakerRequestVolumeThreshold(int value)

我们应该根据我们自己的平时的访问流量去设置,而不是用默认值,比如说,我们认为平时一般的时候,流量也可以在每秒在QPS 100,10秒的滑动窗口就是1000

一般来说,你可以设置这样的一个值,根据你自己的系统的流量去设置

假如说,你设置的太少了,或者太多了,都不太合适

举个例子,你设置一个20,结果在晚上最低峰的时候,刚好是30,可能晚上的时候因为访问不频繁,大量的找不到缓存,可能超时频繁了一些,结果直接就给短路了

(2)circuitBreaker.errorThresholdPercentage

设置异常请求量的百分比,当异常请求达到这个百分比时,就触发打开短路器,默认是50,也就是50%

HystrixCommandProperties.Setter()
.withCircuitBreakerErrorThresholdPercentage(int value)

(3)circuitBreaker.sleepWindowInMilliseconds

设置在短路之后,需要在多长时间内直接reject请求,然后在这段时间之后,再重新导holf-open状态,尝试允许请求通过以及自动恢复,默认值是5000毫秒

HystrixCommandProperties.Setter()
.withCircuitBreakerSleepWindowInMilliseconds(int value)

 

限流过后,就会导致什么呢,比如redis集群崩溃了,雪崩,大量的请求涌入到商品服务调用的command中,是线程池不够

reject,被reject掉的请求就会去执行fallback降级逻辑
那么nginx本地缓存肯定就没了,redis已经崩溃了,ehcache中找不到这条数据对应的缓存

只能从源头的商品服务里面去查询,但是被限流了,这个请求只能走降级方案

stubbed fallback降级机制,残缺的降级

一般这种情况下,就是说,用请求参数中少量的数据,加上纯内存中缓存的少量的数据来提供残缺的数据服务

冷数据,也就是说你可以这么认为,将一些过时的数据,比如一个商品信息一周前的版本,放入大数据的在线存储中,比如比较合适做冷数据存放的是hbase

hadoop,离线批处理,hdfs分布式存储,yarn分布式资源调度(跟hbase没关系),mapreduce分布式计算

hbase,基于hdfs分布式存储基础之上,封装了一个系统,叫做hbase,分布式在线存储,分布式NoSQL数据库,里面可以放大量的冷数据

hbase,可以做商品服务热数据是放mysql,可以将一周前,一个月前的数据快照,做一份冷备放到hbase来备用

发送请求去访问hbase,去加载冷数据,hbase本身是分布式的,所以也是可以承载高并发的访问的(分布式的特性比mysql),即使这个时候大量并发到了hbase,

多级降级机制,先走hbase冷备,然后再走stubbed fallback

缓存雪崩的回顾

1、事前,redis高可用性,redis cluster,sentinal,复制,主从,从->主,双机房部署

2、事中,ehcache可以抗一抗,redis挂掉之后的资源隔离、超时控制、熔断,商品服务的访问限流、多级降级,缓存服务在雪崩场景下存活下来,基于ehcache和存活的商品服务提供数据

3、事后,快速恢复Redis,备份+恢复,快速的缓存预热的方案

posted @ 2019-09-26 21:11  石shi  阅读(1365)  评论(0编辑  收藏  举报