照顾好应用的缓存-应付大流量

本文介绍了如何通过多种策略保持缓存数据的新鲜度,包括利用消息队列实时更新缓存、采用全量与增量方式刷新缓存、使用本地缓存减少数据库负担及实现缓存的高效管理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

概述


为了提升系统的响应速度,通常会系统中使用缓存,例如:中央缓存,本地缓存等。但是使用缓存有好有坏,坏处是,如果缓存数据是旧的,那么应用输出的数据便是错误的数据,可能造成严重的影响。本文介绍一些让缓存保持新鲜以及使用缓存的一些技巧


利用MQ实时刷新缓存


一旦db数据发生变化,则可以发送一条mq消息,通知消费者,信息有变动,消费者感知到后,立刻调用刷新缓存的接口,把数据涮新到中央缓存里。这里有三个点要注意一下:
1、如果缓存中的数据存在依赖关系,那么必须级联的进行刷新,不然会出现,数据在缓存中不一致。
2、MQ可能挂掉,得使用其他辅助方案来刷新中央缓存。比如说,定时任务全量刷,增量刷。
3、如果应用中Mysql使用一主多从,那么一定要注意主从延迟的问题,如下图:
这里写图片描述

一旦消息消费者判断数据已经从master库同步到slave1的时候,就开始调用调用刷缓存的接口,刷新缓存的应用这个时候读取的是slave2,那么可能数据还未从master同步到slave2,那么这个时候读取的数据其实还是旧的,刷到缓存的数据也是旧的。

基于这种情况,有一种办法,就是保证消息消费者和刷新缓存的应用读取的db必须是同一个。这样即使出现主从延迟,也没问题。

备注:一主一从不会出现这种情况。


全量刷中央缓存


可以使用一个job,每天凌晨把所有热点数据刷新到中央缓存里。


增量刷中央缓存


全量刷,有个缺点,就是得等到晚上凌晨,数据才能被刷到中央缓存里。如果想让数据快点刷到中央缓存里,可以使用一个增量的job,每隔两个小时,把最新的热点数据刷到缓存里。使用增量job也注意一个问题,避免高峰期刷。比如说,你的应用是早上十点,晚上八点流量最大,那么这个时候,就不要去刷缓存了,给应用多留一些资源,应付大流量


使用哨兵机制


有些情况下,中央缓存也会缓存外部其他系统的数据,如果这些数据访问比较频繁,那么可以使用哨兵机制,当这些数据快要过期的时候,主动调用外部系统,把数据刷新到中央缓存里。个人认为这是一个相当不错的技巧。因为调用一次外部系统的接口,开销还是很大的,而且也需要时间,如果能提前调用的话,那么将大大提高本系统接口的响应速度。


使用本地缓存


使用本地缓存的时候,有几点要注意
1、本地缓存的选型,到底是使用堆外缓存还是堆内缓存。
堆外缓存有:
OHC、ehcache、OpenHFT Chronicle Map 2、OpenHFT Chronicle Map 3。
堆内的有:ConcurrentHashMap、Google Loading Cache
缓存的数据量比较大的话,使用堆外的,量小的,使用堆内的。

2、注意同一个key的防穿透,就是说,有相同的key并发的访问到本地缓存,那么应该只是让其中一个key穿透过去,其他的key只能等待,防止大量的key穿透过去,对中央缓存或者db造成压力。


本地缓存刷新策略


1、自动过期。这种方式非常的简单,就是设置本地缓存数据的失效时间,比如说,设置5分钟,5分钟后自动失效,请求穿透过去。
如果使用数据过期这种方式的话,要注意,当系统有大流量的时候,要延迟本地缓存数据的失效时间,比如说设置20分钟失效,避免穿透的数据太多

2、发布订阅的方式,在每个应用中部署一个监听者,写数据的一方,一旦把数据写到db后,就通知每个应用的监听者,刷新本地缓存。这种方式稍微有点难度,也不是特别可控。目前我参与的应用,本地缓存数据的刷新策略是自动失效。


做好缓存开关(重要)


无论是中央缓存还是本地缓存,都要设置一个开关:是否从缓存读取数据
因为由于数据原因或者程序的bug,可能出现缓存数据是不正确的,这个时候外部系统发请求过来的时候,
拿到数据就是错的。那么我们可以先利用缓存开关,让请求直接穿透,获取正确数据,这样后续的请求拿到的数据就是对的了。然后同时使用缓存刷新工具,把不正确的数据刷新掉。

特别是,缓存中有很多数据是不对的时候,手动人工刷新缓存可能需要比较长的时间,为了保证后续请求能拿到正确的数据,必须使用缓存开关。


一定要有手动刷新缓存的工具


如果出现缓存数据不正确的情况下,而且数据量不大,那么直接使用缓存刷新工具刷新即可。


统计命中率


为了能知道缓存的命中率,分析缓存框架的效果,最好用程序输出缓存的命中率。如果缓存命中不高的话,就得分析原因了。可能是算法有问题,缓存key的维度有问题等等。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值