性能提升利器——缓存

一、概述

在用户请求的整个链路上处处都能见到缓存的身影。客户端浏览器有缓存,前端CDN静态资源有缓存,后台服务有本地缓存和分布式缓存,数据库有查询缓存,操作系统对磁盘数据有页缓存,CPU对内存数据有高速缓存。如果从源头去获取一个东西代价比较高,那么把它搬到一个更容易获取的地方,之后从这个地方获取更高效,这是缓存解决问题的本质。

二、数据一致性

缓存有像反范式化数据库设计一样的问题:重复数据,有多个地方需要更新数据,所以要保证数据一致性。然而这里的一致性也只是最终一致性,并不是强一致性,从数据更新到缓存更新,这期间查询的缓存数据就是过期的数据。对于强一致性的数据而言,不适合用缓存,如果DB有压力,那么分区是更为合适的选择。

写时更新

在更新原始数据的同时更新缓存,下次访问的缓存数据就是最新的。并发写可能导致脏数据。比如两个写请求,正常情况下DB1 -> Cache1 -> DB2 -> Cache2。并发时可能 DB1 -> DB2 -> Cache2 -> Cache1。DB存在最新的数据,但是缓存里的是旧数据。

读时更新

写时令缓存失效,读数据时将数据加载到缓存。读写并发时可能导致脏数据。getN -> update N to M -> put cache N。库里是M,缓存是N。当变化了某个数据时,需要引起大量缓存的更新,这样写时更新会消耗很多时间,用读时更新就相对合适。

定时更新

在固定时间或者每隔一段时间,将数据重新载入缓存。这适用于数据一致性要求不高的场景。比如Redis会定期检查过期的数据,并清除。(Redis在实现过期的时候同时采用定时更新和读时更新)

三、缓存失效的问题

缓存穿透

对一个根本不存在的数据发起查询,比如id = -1,这类查询会透过缓存落在DB,大量的查询会给DB带来压力。第一、做基本的参数判断,不合法的参数直接快速失败。第二、对该非法key同样做缓存,设置过期时间。防止用非法key重复攻击。第三、布隆过滤器,对于不存在的数据,直接快速失败。布隆过滤器表示不存在的数据一定不存在,而布隆过滤器表示存在的数据也许不存在。这样能过滤掉大部分无效请求,详情参考Redis的布隆过滤器。

缓存击穿

一个拥有大量访问量的key在缓存失效时,会导致请求落到DB。第一、热点key可以不设置过期时间。第二、在失效去DB获取数据时使用双重检查锁来维护缓存数据。这样至少能保证同一时间点,一台机器上最多一个线程去DB获取数据。

缓存雪崩

同一时间段内有大量的缓存失效,导致请求落到DB。第一、热点key可以不设置过期时间。第二、过期时间可以加上一个随机值,使得过期时间分散开。第三、可以将不同的热点数据分布到不同的缓存上,这样也减少缓存的压力。

四、其他注意事项

1.更新缓存失败

缓存更新失败,不做其他处理,势必会导致读取到过期的数据。如果更新失败,可以用异步任务重推,可以设置定时任务定时做数据对其。多次失败后告警,人工介入。

2.缓存维护成本

缓存维护成本包括检查缓存的开销,维护缓存的时间成本和空间成本。如果成本很高,缓存命中率低,带来的收益不佳,需要重新考虑缓存的必要性了。

3.缓存命中率

如果缓存命中率很低,那么需要结合缓存维护成本来考虑是否有必要加这个缓存。应当尽量提高缓存的命中率,充分利用缓存。

4.内存与网络开销

在使用分布式缓存时,需要考虑网络开销的成本。因为缓存本来就很快,相比而言,网络开销的占比就增大了。特别是多次从缓存中获取数据,需要考虑叠加的网络开销。尽量通过更少的请求数量,获取一批所需的缓存数据。分布式缓存系统主要关注的就是内存和带宽两方面。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值