- 雪崩(Cache Avalanche):- 定义: 雪崩是指缓存中的大量数据在同一时间失效或过期,导致大量的请求直接访问底层数据库或服务,从而对数据库或服务造成巨大的压力。- 例子: 假设有一组缓存键,它们的过期时间是相同的,并且在同一时刻失效。当这些键失效时,大量的请求同时到达后端服务,由于缓存未命中,导致大量的请求落到底层数据库,引起数据库压力骤增。
- 穿透(Cache Penetration):- 定义: 穿透是指恶意请求或无效请求经过缓存直接访问底层数据库或服务,由于缓存无法命中有效数据,导致请求直接穿透到底层,对底层系统造成不必要的负担。- 例子: 攻击者通过构造恶意的请求,故意使得请求的 key 无法在缓存中找到有效数据。如果缓存无法防范这种攻击,大量的请求将直接落到底层服务,引起服务压力。
- 击穿(Cache Breakdown):- 定义: 击穿是指针对某一特定的缓存 key 进行频繁请求,而这个 key 在缓存中失效,导致请求直接访问底层数据库或服务。- 例子: 假设有一个热门的商品详情页,缓存了商品信息的 key。当这个商品详情页的缓存失效时,大量请求涌入,直接落到底层服务,由于这个 key 对应的数据是热门的,导致数据库压力骤增。
防范措施:
- 对于雪崩,可以采用缓存失效时间设置随机值,分散缓存过期时间,或者使用更为稳妥的缓存失效策略。
- 对于穿透,可以使用布隆过滤器等机制来过滤掉无效的请求,确保无效请求不会直接访问底层服务。
- 对于击穿,可以使用互斥锁或者在缓存失效时通过异步方式进行缓存更新,保证只有一个请求去访问底层服务。
下面主要详细解释一下击穿问题:
对于击穿问题,解决方案主要是通过互斥锁(Mutex)或者异步方式进行缓存更新。以下是对这两种方案的详细解释:
- 互斥锁(Mutex):- 概念: 互斥锁是一种同步机制,用于控制对共享资源的访问,确保在同一时刻只有一个线程能够访问该资源。在缓存失效时,使用互斥锁可以确保只有一个请求能够去访问底层服务,其他请求需要等待缓存更新完成。- 实现: 当检测到缓存失效时,第一个请求获取互斥锁,负责去更新缓存。其他请求在获取互斥锁之前被阻塞,直到第一个请求完成缓存更新,释放互斥锁。- 优点: 简单有效,确保只有一个请求能够访问底层服务,避免了大量请求同时穿透到底层。
- 异步方式进行缓存更新:- 概念: 异步方式是指在缓存失效时,不立即去更新缓存,而是通过异步任务或消息队列等方式,在后台进行缓存的更新操作。这样可以确保只有一个请求触发了缓存更新,而其他请求不会直接访问底层服务。- 实现: 当检测到缓存失效时,第一个请求触发异步任务或消息队列,负责后台更新缓存。其他请求不等待缓存更新完成,而是继续使用旧的缓存数据。一旦异步任务完成,新的缓存数据可用,后续请求再使用更新后的缓存。- 优点: 异步方式不阻塞请求,提高了系统的并发能力。对于短时间内大量请求穿透一个失效的缓存的情况,可以减轻对底层服务的冲击。
选择互斥锁还是异步方式取决于具体的业务场景和系统需求。互斥锁适用于需要立即更新缓存且并发请求较少的情况,而异步方式适用于更为高并发的场景,可以降低对底层服务的压力。
版权归原作者 严定洲 所有, 如有侵权,请联系我们删除。