缓存设计
首先缓存设计。我们怎么设计一套缓存呢。大致的套路基本上都是一个LocalCache,一个分布式Cache (Redis) ,大体的架构图将像下面所示。
缓存前提
缓存主要来缓存热点的key。所以有热key才行,但是基本上对于一般的app,活跃用户基本在固定的人群,所以大部分这个套路都是有用的。但是缓存不是DB,它的定位是热点数据而不是全量数据,所以一般100GB 足以。
缓存好处
好处就是将DB的压力转化到了Redis上,这样可以降低服务的延时,降低DB的压力。
缓存穿透
缓存穿透指的是有相关的非法key导致 分布式缓存根本没有命中这个key,这个时候大量的流量打到了DB。对于缓存穿透在工作中我碰到了一个case,db 下游返回了一个非法的数据,因为是非法的数据后,应用没有把它写到Redis 和 LocalCache中。导致每次这个key 的请求都会穿透到DB ,导致DB 压力变大。
个人理解为了处理缓存穿透,这里需要对非法key进行处理。可以建立一个非法key的LocalCache,这个非法LocalCache的每个key的超时时间要尽可能的小比如10s,20s。这个时候我们从Redis Miss 后先去 非法Cache 检查一遍,没有的话再去读db。
缓存雪崩
缓存雪崩指线上服务有大量的key Miss,这个时候导致大量的流量打到DB。
雪崩发生可能的场景
- Redis集群大量的服务挂了
- DB 大量的服务挂了,这个时候大多数 Redis key Miss 后,会有大量的流量打到DB。
第二个case,我遇到过有一次下游DB服务做了相关服务鉴权方面的事情,这个时候线上服务打到DB后连接被拒绝掉。这个时候如果没及时发现,等Redis的大量key超时后,就会发生雪崩
针对缓存血崩我个人感觉处理的方法步骤如下:
- 设置一个分布式的配置key 写到 etcd 里面 或者 zk 里面。如果及时发现的话,开启开关。这个时候服务将不再访问访问下游,并且这个时候将LocalCache超时时间设置为永久或者很长时间。
- 及时限流,丢弃大部分对下游的请求流量。