如何用好缓存?全面梳理(第三篇)
缓存系列文章,接上一篇
讲了这么多,那我们在使用缓存有没有要注意的问题,有没有什么潜在的坑。我们来看几个问题案例。
黑客、竞品对手恶意攻击,缓存没有起到分担存储系统访问压力,系统拖垮
布隆过滤器拥有极高的性能
时间复杂度O(1),二进制位存储,省空间,20亿的数组约占238M.
缺点:由于hash碰撞,只能支持未命中的判断,如果布隆过滤器认为值不存在,那么值一定是不存在的,无需查询缓存也无需查询数据库,存在极小概率的误判断。不支持元素删除
流量控制。加锁,只允许第一次请求去预热缓存,预热完成之前,后续请求直接返回或阻塞等待结果
另一种方法是缓存预热,在大批量请求到来以前,先主动将缓存填充好。这种方法操作简单高效,但局限性是需要提前知道哪些数据可能引发缓存穿透的问题。
看几个例子。大的电商公司会有比价系统,用于做运营策略,知彼知己,百战不殆。爬取竞品公司商品价格,将冷数据加载到缓存中,挤掉热点数据。压力转嫁DB。导致数据库出现问题。一般不会瞬间造成系统不可用,缓慢过程,报警,监控命中率。风控层面做干预,识别非法来源。lru-k
新业务上线,比如秒杀活动,缓存未预热。很容易引发雪崩。解决:一种方式提前将数据预热到cache;另一种,灰度,逐步开放给新用户,做好流量阶梯缓冲
我们经常听到系统不停机完成一些架构升级,飞行的飞机上换发动机引擎,说明技术实力很强。但有些系统停机后,很难再启动,为什么?一启动,大流量就把DB打死了。
最后提一个点,我们预热缓存经常通过跑批任务,缓存的过期时间不要过于集中。很容易引发问题。
例如,某明星微博发布恋爱公告,短时间内吸引上千万的用户来围观。
注意事项。缓存副本设计有一个细节需要注意,就是不同的缓存副本不要设置统一的过期时间,否则就会出现所有缓存副本同时生成同时失效的情况,从而引发缓存雪崩效应。正确的做法是设定一个过期时间范围,不同的缓存副本的过期时间是指定范围内的随机值。
重试机制。代码重试3次。失败记录到DB中,扫描任务定时补偿缓存
操作DB成功后,发MQ消息,异步更新缓存,如果更新失败,借助MQ框架自身的重试机制来保证,想阿里开源的RocketMQ支持18级的延迟规则,最低1s,最高级2个小时,如果不 ack success,会一直重试。
缓存功能具体怎样整合集成到 Web 应用中。有很多方式,每一种方式都意味着一个切入点。首先看下编程方式。使用编程的方式来获取缓存数据,是最常见的方式。这种方式比较灵活
配置文件注入也比较常见,比如 MyBatis 在 mapper 标签中可以指定 cache 标签,通过这种方式就可以把选定的缓存框架注入到这个持久层框架中。对于指定映射的数据,再次访问时会优先从缓存中查找。对于热点数据效果比较好。
最后我们来做下总结,使用缓存要注意哪些问题。
空间大小:避免空间不足,导致热数据被置换出去,影响缓存命中率
缓存对象粒度,考虑尽可能复用,不要一个小字段修改导整个大对象全部失效
对象大小。单key下挂了5M的大对象,反序列化,取部分字段数据,当业务并发量上涨,占用太多带宽,把网卡打爆,进而影响其它正常业务访问
最后建议,软件的系统架构是一个不断衍化的过程。”过早的优化是万恶之源“,如果没有达到引入缓存的条件,尽量不要过早使用缓存,缓存的坑很多,经常引发一些一致性的问题,维护成本极高。
终结篇,谢谢收藏!
往期推荐
关注【微观技术】
我们热衷于收集&分享高并发、系统架构、微服务、消息中间件、 RPC框架、高性能缓存、搜索、分布式数据框架、分布式协同服务、分布式配置中心、中台架构、领域驱动设计、系统监控、系统稳定性等技术知识。
关注公众号,后台回复“中台”,下载PDF学习资料