缓存三重门:穿透、雪崩、击穿的谜题与守护策略

1、缓存穿透

缓存穿透是一种缓存与数据库交互中的问题,它发生在用户或攻击者请求大量缓存中不存在的数据时。在正常情况下,缓存是用来减轻数据库的压力的,通过保存经常访问的数据。但是,在缓存穿透的场景中,请求直接“穿透”了缓存层,直接请求到了数据库层,这就可能导致数据库过载,严重时甚至可能导致服务不可用。

缓存穿透的影响可以从轻微的性能下降到严重的服务中断。对于一个高流量的网站,例如电子商务平台,这种攻击可以在短时间内生成数以万计的查询,导致数据库压力巨大。不仅影响了正常用户的使用体验,还可能造成其他相关服务的连锁反应,影响整个系统的稳定性。

解决方案

1. 参数校验

最基础的防御措施是强化输入参数的校验,确保查询请求是合法的。例如,对于商品ID,可以确保它们符合特定的格式,并且在一个合理的数值范围内。

2. 布隆过滤器

布隆过滤器是一种高效的数据结构,可以用来测试一个元素是否是集合的成员。在数据库查询之前,先使用布隆过滤器检查元素是否可能存在。如果布隆过滤器表示元素绝对不在集合中,就可以直接返回错误,而不必查询数据库。

布隆过滤器 底层使用 bit 数组存储数据,该数组中的元素默认值是0。

布隆过滤器第一次初始化的时候,会把数据库中所有已存在的 key,经过一些列的 hash 算法(比如:三次 hash 算法)计算,每个 key 都会计算出多个位置,然后把这些位置上的元素值设置成1。

在这里插入图片描述

之后,有用户 key 请求过来的时候,再用相同的 hash 算法计算位置。

  • 如果多个位置中的元素值都是1,则说明该 key 在数据库中已存在。这时允许继续往后面操作。

  • 如果有1个以上的位置上的元素值是0,则说明该 key 在数据库中不存在。这时可以拒绝该请求,而直接返回。

使用布隆过滤器确实可以解决缓存穿透问题,但同时也带来了两个问题:

  1. 存在误判的情况。(如果想减少误判率,可以适当增加hash函数)
  2. 存在数据更新问题。(如果数据库中的数据更新了,需要同步更新布隆过滤器。但它跟数据库是两个数据源,就可能存在数据不一致的情况。)

布隆过滤器要看实际业务场景再决定是否使用,它帮我们解决了缓存穿透问题,但同时了带来了新的问题。

3. 缓存空结果

另一种策略是缓存空结果。对于查询无结果的请求,系统也会将这个结果(即空或者错误信息)缓存到缓存层,并设置一个较短的过期时间。这样即便是不存在的数据,也可以被缓存层拦截,减轻数据库的负担。

4. 分布式缓存

使用分布式缓存可以确保数据不容易全部丢失,降低单点缓存被穿透的风险,并且提高了缓存的可用性和容错性。

5. 限流和降级

当检测到异常请求流量时,可以采取限流措施,比如使用令牌桶算法限制请求速率。在系统负载过高时,也可以对服务进行降级处理,先保证核心服务的可用性。

2、缓存雪崩

缓存雪崩是缓存系统中一种较为常见且潜在危险的现象,它指的是在缓存层面发生的大规模的缓存失效事件,这通常会导致突然而巨大的数据库请求流量,从而造成数据库服务的短时间内不可用,影响整体系统的稳定性和可靠性。

缓存雪崩通常发生在缓存系统中大量或全部缓存项集中在同一时间点过期失效的情况,此时对这些缓存数据的查询请求会同时转发到数据库。如果后端数据库不能承受这么大的读取压力,就可能导致数据库访问缓慢甚至宕机,进而影响到整个系统的运行。

缓存雪崩不仅会导致数据库压力骤增,还会影响到依赖数据库的中间件、业务逻辑处理层等,造成整个应用服务的响应时间延长或者服务不可用。对于电商平台、金融服务等对系统稳定性要求极高的业务来说,缓存雪崩可能会带来重大的经济损失和品牌信誉的损害。

对策与解决方案

1. 设置不同的过期时间

为了避免大量缓存同时失效,可以给不同的缓存项设置不同的过期时间,使得缓存失效的时间点分散,减少同时大量访问数据库的可能性。

2. 使用缓存数据的双层结构

设置两层缓存,一层是热数据缓存,一层是冷数据缓存,即使热数据缓存失效,冷数据缓存仍然可以提供服务,从而避免直接对数据库的访问。

3. 缓存预热

系统上线后,可以根据业务需求主动预先加载一些热点数据到缓存中,这样即使在缓存失效的情况下,也能快速重建缓存数据。

4. 降级和熔断机制

当缓存失效导致数据库压力过大时,可以启动降级机制,比如临时关闭一些非核心服务,保证核心服务的可用性;使用熔断机制暂时拒绝一部分请求,避免系统完全崩溃。

5. 分布式缓存与读写分离

引入分布式缓存,确保即使部分缓存区域失效,也不会影响整体缓存系统的稳定性。同时实施数据库读写分离,减轻主数据库的读取压力。

6. 限流措施

通过限流措施如令牌桶、漏桶等算法,控制在高流量下进入系统的请求量,避免过大的流量冲击数据库。

3、缓存击穿

在高并发系统中,缓存是一种关键的技术,用于提高数据读取速度和减少后端系统的负载。然而,即使有了缓存,也需要解决一些潜在的问题,其中之一就是缓存击穿。本文将讨论缓存击穿的原因、影响以及如何防范这一问题。

缓存击穿指的是当缓存中某个热点数据过期时,同时有大量的并发请求这个数据,导致所有请求都直接打到数据库上,从而引发数据库的压力骤增。与缓存穿透不同,缓存击穿通常发生在一个热点key突然失效的情况下。

缓存击穿的影响较为局限,主要集中在单个热点数据上,但其对系统的影响却可能非常严重。一旦发生缓存击穿,大量的请求会在短时间内冲击数据库,造成数据库响应缓慢甚至宕机,严重影响用户体验和系统稳定性。

防御策略

1. 设置热点数据永不过期

对于极端热点的数据,可以将其缓存设置为永不过期,或者拥有非常长的过期时间,并采用定时任务在后台更新这些热点数据。

2. 使用互斥锁

当缓存失效时,不是所有的请求都去查询数据库加载数据,而是使用互斥锁(或者分布式锁)的方式,只让一个请求去查询数据库并更新缓存,其他请求等待缓存更新后再进行访问。

3. 预加载与数据预热

在系统启动或者缓存即将过期之前,提前加载数据到缓存中,这样就避免了突然的缓存击穿现象。

4. 设置缓存的逻辑过期

缓存项设置两个过期时间,一个是逻辑过期时间,一个是物理过期时间。当缓存逻辑过期时,触发缓存的更新操作,但在物理过期之前,仍然可以读取旧的缓存数据,保证数据的可用性。

5. 延长过期时间

对于即将过期的热点数据,动态地延长其过期时间,直到新的值被计算并存储到缓存中。

6. 降级和熔断机制

实现降级机制,当缓存击穿发生时,临时关闭一些非核心服务;利用熔断机制,合理设置阈值,一旦超过阈值,暂时停止服务,等系统恢复后再次提供服务。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值