什么情况会导致缓存不可用?
-
单点问题:
什么是单点问题呢?就是我们在使用缓存时,有时候由于 QPS、内存容量只需要一个端口(此处的一个端口是指一主一从)就可以扛住所有读写请求时,比如写 QPS 5k,读 QPS 30k,内存 5G;根据这个数据规模,DBA 在部署资源时会选择只部署一个节点。当缓存资源由于某些情况导致服务器宕机或服务不可用时,由于只部署了一个端口,从而导致当前整个应用服务不可用(这种情况之前在实际生产环境中真实发生过,直接炸裂),这就是所谓的单点问题;其实在分布式架构中,为了做到服务的高可用,要尽量去避免单点问题,做到鸡蛋尽量不放在一个篮子里来尽量保证服务的可用性。
-
缓存穿透/缓存击穿
缓存穿透/缓存击穿是指某些时刻由于有些热 key 失效或者是过期,导致在一瞬间大量请求绕过缓存直接打到 DB 上,由于 DB 的读写 qps 并不高,从而导致 DB 直接瞬间被打挂,尤其是在微博这种应用上,突发热点流量加上缓存设计不合理导致热 key 过期,就会发生缓存击穿的情况。
-
缓存雪崩
缓存雪崩是指由于缓存过期时间设计不合理,缓存数据过期时间集中,导致在某一时刻缓存中数据大面积过期,从而导致缓存的 miss 率大大增加,由于缓存没有拦住请求导致大量请求落到 DB 上,最终导致后端 DB 资源被彻底打挂,即使重启 DB 也会被大量请求瞬间再次打挂。
如何设计高可用的缓存?
-
单点问题解决方案
首先,单端口在资源申请阶段部署为多端口的(大于一个端口),同时每个端口至少部署为一主一从且分布在不同的节点上;通过此种部署方式,会有如下几个好处:
-
假设某个从节点服务不可用时,将读请求转移到主节点上可继续提供服务,当从节点恢复后再加入到集群中继续提供服务。
-
假设集群中某几个节点服务不可用时,此时最坏的情况也只是影响部分用户的功能使用。
其次,在多端口部署的基础上,在机房层面做到多机房灾备;此种缓存的做法是:假设一个缓存部署两份,而这两份缓存部署在不同的机房中,这样的话,即使其中一个机房发生极端情况,可以将流量切换到另外一个机房中,从而做到机房层面的高可用。
最后,可以使用一致性 hash 算法,使用机器的 ip 或者域名做 hash 操作,分布在一个虚拟的环上,同样对于 key 也做相同的 hash 操作,当 key 得到一个 hash 值后,顺时针移动直到遇到第一个节点,然后将 key 对应的 value 存储到该节点上;此种做法是节点动态上下线的时候只需要对部分 key 做 rehash 操作,但是此种方案的缺点是:节点动态上下线后,key 经过 rehash 操作后导致各个节点数据分布不均,也就导致各个节点的服务承载的压力不均不可控。
-
缓存穿透/缓存击穿的解决方案
缓存击穿是由于热 key 失效导致的,所以第一种方案是:可以根据业务场景,选择可以将热 key 直接全部缓存到缓存中并且永远不过期,通过此种方式来避免热 key 因为过期的问题导致缓存击穿;第二种方案是:由于热 key 一般情况下并不是很多,所以我们可以考虑使用 localCache,在系统启动时,预先将热点数据全部加载到内存中,只要服务器不发生宕机就可以一直正常提供服务。
-
缓存雪崩的解决方案
缓存雪崩是在某一时刻,缓存中数据大量集中过期导致缓存不可用,对于此种情况,一般是在缓存 key 设计时,对 key 增加一个一定时间范围内的随机时间戳,使得 key 过期分散开来,从而避免所有 key 同时过期的尴尬情况。
总结
本文主要介绍了实际生产环境中缓存该如何做到高可用,从而避免由于缓存不可用而导致整个系统崩溃。