缓存的设计与使用

一、引言

谈到后台服务缓存问题,在构建和优化业务服务时
第一想到的应该是优化数据库,比如数据库模型设计、SQL结构化查询语句优化,慢查询往往是系统性能杀手。

第二是使用缓存。但是相比于其他优化手段,缓存的使用并不是零成本的,任何系统使用缓存,都会遇到两大问题:

1、数据不一致问题
2、系统复杂性增加

缓存的设计与使用

衡量缓存设计好坏的衡量指标是缓存命中率,缓存的命中率=缓存命中次数/请求次数,命中率越高,缓存的使用率越高。

缓存的适用场景总的来说是访问高频读低频写的数据。相反的对数据要求苛刻,变化频率高、访问频率低的数据不能缓存。设计和使用缓存首先要了解服务、DB、Cache的性能情况,一般情况下,DB的响应是10ms级。

本地缓存可用hashmap(注意并发)、guava-cache(推荐)等实现。对于一致性要求不高且缓存命中率较高的数据服务,本地缓存可以减少服务端调用次数;集中缓存又称分布式缓存,实现由redis(推荐),memcache等。

分布式缓存的设计与使用

缓存的设计模式一般分为四种Cache aside,Read through,Write through,Write behind caching.

Cache Aside Pattern

Cache aside pattern是最常用的方式,其具体逻辑如下:
失效:应用程序先从cache取数据,没有得到,则从数据库中取数据,成功后,放在缓存中。
命中:应用程序从cache中取数据,取到后返回。
更新:先把数据存到数据库中,成功后,再让缓存失效

缓存引入的问题

缓存系统一定程度上极大提升系统并发能力,但同样也增加额外技术考虑因素,比如缓存雪崩、缓存穿透、缓存更新与数据一致性

缓存穿透

缓存穿透是指查询的key不存在,从而缓存查询不到而查询你了数据库。若是这样的key恰好并发请求很大,那么就会对数据库造成不必要的压力。比如一个黑客用一堆不存在的key访问数据,大量请求发送到数据库,数据库压力过大而宕机,怎么解决呢?

1、把所有存在的key都存到另外一个存储的Set集合里,查询时可以先查询key是否存在;
2、将这些key对应的值设置为null丢到缓存里面去。后面再出现查询这个key的请求的时候,直接返回null,再根据业务需求设置过期时间。
3、BloomFilter类似于一个hbase set用来判断某个元素(key)是否存在于某个集合中。这种方式在大数据场景应用比较多,比如Hbase中使用它去判断数据是否在磁盘上。这种方案可以加在第1/2种方案中,在缓存之前加一层BloomFilter,在查询的时候先去BloomFliter去查询key是否存在,如果不存在就直接返回,存在再走查询。

缓存击穿

在高并发的系统中,大量的请求同时查询一个key时,这个key刚好失效了,就会导致大量的请求都打到数据库上面去。这种现象我们称为缓存击穿。造成缓存击穿的原因是多个线程同时去查询数据库,那么我们可以在第一个查询数据的请求上使用一个互斥锁。其他的线程进入等待状态,等第一个线程查询到了数据,然后做缓存。后面的线程进来发现已经有缓存了,就直接走缓存。

缓存雪崩

定义:缓存雪崩是指缓存系统失效,导致大量请求同时进行数据回源,导致数据源压力骤增而崩溃。两种情况会导致此问题:1、多个缓存同时失效;2、缓存系统崩溃,缓存同时失效

针对多个缓存数据同时失效的问题,可以将缓存时间离散化,根据缓存数据访问规律和缓存数据不一致的敏感性要求来选择缓存时间。

如果是第二个问题,缓存系统整体故障,则整个缓存系统不可用,大量回源请求,且由于缓存系统故障无法回写缓存,导致无法快速恢复。

这是缓存系统的引入,在解决高性能、高并发的同时,引入新的故障点。

考虑此问题,应从事前、事故中、事后不同阶段考虑;

事前:增加缓存系统高可用方案设计,避免出现系统性障碍

事故中:增加多级缓存,在单一缓存故障时,仍有其他缓存系统可用,如之前项目中使用的三级缓存方案:内存级缓存->Memcached->Redis这样的方案;启用熔断限流机制,只允许可承受流量,避免全部流量压垮系统

事后:缓存数据持久化,在故障后快速恢复缓存系统

总结

使用缓存会增加系统复杂性,应根据业务考虑是否需要使用以及使用分布式缓存还是本地缓存,设置合理的混村策略可用提高系统的性能,同时要合理的规避可能由于引入缓存而增加的风险。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值