Redis 缓存雪崩、穿透、击穿、预热

Redis缓存问题及其解决方案:雪崩、击穿、穿透与预热
本文详细讨论了Redis缓存中遇到的常见问题,如缓存穿透、击穿和雪崩,分析了其产生的原因,并提供了布隆过滤器、互斥锁等解决方案,以及缓存预热策略,以提升系统性能和应对高并发场景。

        在实际工程中,Redis 缓存问题常伴随高并发场景出现。例如,电商大促、活动报名、突发新闻时,由于缓存失效导致大量请求访问数据库,导致雪崩击穿穿透等问题。因此,新系统上线前需预热缓存,以应对高并发,减轻数据库压力。本章主要围绕这几个核心问题,针对产生场景、分析原因、并给出相应的解决方案。

常见问题:

1. 缓存穿透

1.1 什么是缓存穿透

一句话,就是查询一条根本没有的记录。它既不存在于redis中,也不存在数据库中。一般我们的查询顺序是先查redis、再查数据库。每次请求最终都会访问到数据库。造成数据库访问压力。这种现象叫缓存穿透

问题描述
        key 对应的数据在数据源并不存在,每次针对此 key 的请求从缓存获取不到,请求都会压到数据源(数据库),从而可能压垮数据源。比如用一个不存在的用户 id 获取用户信息,不论缓存还是数据库都没有,若黑客利用此漏洞进行攻击可能压垮数据库。

1.2 产生原因

  • 查询记录在redis和数据库均不存在

  • 恶意攻击

缓存穿透发生的条件:

  • 应用服务器压力变大
  • redis 命中率降低
  • 一直查询数据库,使得数据库压力太大而压垮

其实 redis 在这个过程中一直平稳运行,崩溃的是我们的数据库(如 MySQL)。

缓存穿透发生的原因:黑客或者其他非正常用户频繁进行很多非正常的 url 访问,使得 redis 查询不到数据库。

1.3 解决方案

方案一:使用布隆过滤器

使用布隆过滤器解决缓存穿透问题具体流程如下:

流程说明:

  • Web端发起请求到App服务应用

  • 经过布隆过滤器判断key是否存在

  • 若不存在,直接返回null

  • 若key存在或者被误判(下文详述),查询redis

  • 若redis中有结果,直接返回

  • 未查到,则查询数据库返回结果

  • 数据库查到结果,返回结果。并将对应key回写redis

  • 未查到,则返回null

方案二:缓存空对象或者默认值

针对要查询的数据,需求层面沟通,可以在Redis里存一个缺省值(比如,零、负数、defaultNull等)。

流程描述:

  • 先去redis查键user:xxxxxx没有,再去mysql查没有获得 ,这就发生了一次穿透现象;

  • 第一次来查询user:xxxxxx,redis和mysql都没有,返回null给调用者;

  • 将 user:xxxxxx,defaultNull 回写redis;

  • 第二次查user:xxxxxx,此时redis就有值了。

可以直接从Redis中读取default缺省值返回给业务应用程序,避免了把大量请求发送给mysql处理,打爆mysql。

但是,此方法只能解决key相同的情况,但是无法应对黑客恶意攻击。

解决方案:

  • 对空值缓存:如果一个查询返回的数据为空(不管是数据是否不存在),我们仍然把这个空结果(null)进行缓存,设置空结果的过期时间会很短,最长不超过五分钟。
  • 设置可访问的名单(白名单):使用 bitmaps 类型定义一个可以访问的名单,名单 id 作为 bitmaps 的偏移量,每次访问和 bitmap 里面的 id 进行比较,如果访问 id 不在 bitmaps 里面,进行拦截,不允许访问。
  • 采用布隆过滤器:布隆过滤器(Bloom Filter)是 1970 年由布隆提出的。它实际上是一个很长的二进制向量 (位图) 和一系列随机映射函数(哈希函数)。布隆过滤器可以用于检索一个元素是否在一个集合中。它的优点是空间效率和查询时间都远远超过一般的算法,缺点是有一定的误识别率和删除困难。
  • 进行实时监控:当发现 Redis 的命中率开始急速降低,需要排查访问对象和访问的数据,和运维人员配合,可以设置黑名单限制服务。

2. 缓存击穿

2.1 什么是缓存击穿

一句话,就是热点key突然失效了,大量请求暴击数据库。关键词:大量请求、同一个热点key、正好失效。

问题描述
        key 对应的数据存在,但在 redis 中过期,此时若有大量并发请求过来,这些请求发现缓存过期一般都会从后端数据库加载数据并回设到缓存,这个时候大并发的请求可能会瞬间把后端数据库压垮。

2.2 产生原因(发生场景)

  • 某个key以到过期时间,但是还是被访问到

  • key被删除,但是被访问到

  • 如,某电商网站的今日特卖

缓存击穿

缓存穿透缓存击穿缓存雪崩是常见的缓存问题,下面是关于Redis缓存穿透缓存击穿缓存雪崩的介绍: 1. 缓存穿透缓存穿透是指当一个请求查询一个不存在于缓存中的数据时,由于缓存无法命中,请求会直接访问数据库。这种情况下,如果有大量的请求查询不存在的数据,会导致数据库压力过大,影响系统性能。 2. 缓存击穿缓存击穿是指当一个热点数据的缓存过期或失效时,大量的请求同时访问该数据,导致缓存无法命中,请求会直接访问数据库。这种情况下,数据库会承受巨大的压力,可能导致数据库崩溃。 3. 缓存雪崩缓存雪崩是指当缓存中的大量数据同时过期或失效时,大量的请求会直接访问数据库,导致数据库压力剧增,性能下降甚至系统崩溃。缓存雪崩通常是由于缓存服务器故障、缓存设置不合理或者缓存数据过期时间设置不当等原因引起的。 为了避免缓存穿透缓存击穿缓存雪崩问题,可以采取以下措施: - 缓存穿透:可以在应用层对查询的数据进行校验,如果数据不存在,则不进行缓存操作,避免大量无效的请求访问数据库。 - 缓存击穿:可以互斥锁或分布式锁来保护热点数据的问,当缓存失效时,只允许一个请求访问数据库并更新缓存,其他请求等待缓存更新完成后再从缓存中获取数据。 - 缓存雪崩:可以采用多级缓存缓存预热、设置合理的缓存过期时间等策略来避免大量缓存同时失效,保证系统的稳定性性能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值