缓存系统的频繁透传和雪崩问题

1 频繁透传

1.1 背景

目前分布式存储系统通常都会分为至少两个层次:

  • 缓存存储(通常包括MC,Redis等)
  • 落地存储(例如mysql集群)

缓存系统的特点是访存速度快,但是也存在成本高,断电后数据丢失等问题,数据库系统一般访存的速度较慢,但是成本较低,且适合数据长时间的存储。

根据80,20的规律,一个站点的80%的访问一般都集中在20%的数据上(在实际生成环境中这个比例可能更加夸张),因此可以把热门的数据缓存到缓存系统中,使得大部分的访问直接从访存速度快的缓存中获取数据,来提高请求的响应速度,这样既能提升用户体验又能提高站点的并发量。当一个请求到来的时候,如果请求的数据在缓存中没有,这个时候访存就会透传DB层,从DB层取到数据之后,返回给用户的同时将数据缓存到缓存系统中,下一次的请求就可以直接从缓存中取数据。利用这种规则,系统经过一段时间的运行,热数据基本都可以缓存到缓存系统中,站点或者服务的响应和并发都大幅度提高。

1.2 问题

上述双层存储系统看似比较完善,但是会有一个潜在的问题,就是如果被访问的数据本身就不存在,那么即使透传到DB还是取不到数据,这个时候给用户返回空,但是并没有数据可以缓存起来,下一次访问这个数据的时候就仍会透传到DB去,整个系统因为频繁的数据IO响应速度降低,并发支持变差。

这里我们举例子说明一下:
假设微博使用了这种双层的存储系统,大部分用户访问微博的时候都是访问的是缓存系统,响应速度很快,这个时候一个明星刚刚开通了微博但是还没发布过微博,他的粉丝们纷纷过来查看的他的微博,然后系统发现缓存中没有微博,于是就去DB中去查询,但是DB中也没有,于是每个粉丝的访问都会透传到DB,在这种情况下,系统的响应速度明显会降低。

1.3 解决方案

这种由于数据不存在而导致的频繁透传问题,一般可以有两种解决方案

  • 完全信任缓存系统,如果缓存中没有就当作没有。这种方案下需要做好DB和缓存系统的同步,即写数据进行双写,同时利用定时脚本把数据刷到缓存中。这种方案的问题也比较明显,就是需要缓存全量数据,当数据量较大的时候不太合理。
  • 调整缓存策略,当用户透传DB取不到数据的时候,也将这个空数据‘缓存起来’,即该数据就是没有,你就不要去查DB了,使用这种方案的时候要注意需要给这个数据设置一个较短的过期时间,尽量避免数据不一致的问题。

个人比较倾向第二种解决方案。

2 雪崩效应

2.1 问题描述

雪崩效应类似于蝴蝶效应,说的都是一个小因素的变化,却往往有着无比强大的力量,以至于最后改变整体结构、产生意想不到的结果。
当缓存服务器重启或者大量缓存集中在某一个时间段失效,这样在失效的时候,也会给后端系统(比如DB)带来很大压力。

2.2 解决方案

  • 在缓存失效后,通过加锁或者队列来控制读数据库写缓存的线程数量。比如对某个key只允许一个线程查询数据和写缓存,其他线程等待。
  • 不同的key,设置不同的过期时间,让缓存失效的时间点尽量均匀。
  • 做二级缓存,A1为原始缓存,A2为拷贝缓存,A1失效时,可以访问A2,A1缓存失效时间设置为短期,A2设置为长期(目前我们系统中就是使用了MC和Redis两层缓存)

2.3 高并发时的雪崩

这个是补充的一点,在高并发系统中如果不做好过载保护,将会带来雪崩效应的结果。

这里举一个现实工作中的例子来说明,在我司服务请求调度策略中,分为了几个级别

  • 同机房
  • 同IDC
  • 同城
  • 同大区

请求优先打到同机房的机器中,如果同机房的机器服务不可用将会依次飘到同IDC,同城,同大区。而在实际生成环境中,为了节省运维成本,每个服务器基本都是满负荷在跑,在其最大处理能力的范围内尽可能多处理请求(机器要是跑出低负载要被领导批的,;-)),这个时候某一台或者某几台机器突然宕机了,服务器不可用了,那么原本要打到这些机器上的请求就会飘到更高备份级别的机器上去,那么这些原本可用的机器的访问量突然增大,导致了大面积超时,变得不可用了,那么相应的这些请求就会继续向上飘,最后的结果就是系统崩溃掉。。。

对于这种雪崩效应,通过可以通过下面的一些措施来避免

  • 每个系统要做好自我保护,量力而为,而不是尽力而为。对于超出自己处理能力范围的请求,要勇于拒绝。
  • 前端系统有保护后端系统的义务,后端承诺多大的能力,就只给到后端多大的压力。
  • 当过载发生时,该拒绝的请求(1、超出整个系统处理能力范围的;2、已经超时的无效请求)越早拒绝越好。比如机场到市区的高速上,刚出机场就有电子公示牌显示,进入市区某某路段拥堵,请绕行。
  • 中间层server对后端发送请求,重试机制要慎用,一定要用的话要有严格频率控制。
  • 当雪崩发生了,直接清空雪球队列(例如重启进程可以清空socket 缓冲区)可能是快速恢复的有效方法。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值