Redis应用场景:缓存

488 阅读5分钟

在日常的工作中,Redis最常用的场景就是缓存场景,为什么Redis能作为缓存呢?

缓存的特征

系统中,不同层访问速度不一样,缓存一定是一个快速子系统,在一些业务场景中,我们把频繁访问的数据放在缓存中,就是为了避免从慢速子系统中存取数据,加快数据的访问速度:

image.png

缓存处理请求的两种情况

把Redis用作缓存时,我们会把Redis部署在数据库的前端,业务应用在访问数据时,会先查询Redis中是否保存了相应的数据,所以,使用Redis缓存会有两种情况:

  1. 缓存命中:Redis中有数据,直接读取Redis;
  2. 缓存缺失:Redis中没有数据,从后端数据库中读取,并且把缺失的数据写入Redis;

缓存淘汰策略

Redis提供了8种淘汰策略(包括Redis4.0之后的2种新策略)可以分为三类:

  • 不进行数据淘汰:noeviction
  • 设置了过期时间的数据中进行淘汰:volatile-random、volatile-ttl、volatile-lru、volatile-lfu(Redis 4.0 后新增)
  • 所有数据范围内进行淘汰:allkeys-lru、allkeys-random、allkeys-lfu(Redis 4.0 后新增)

其中Redis默认策略是noeviction,也就是说,如果Redis缓存被写满了,Redis就不再提供服务,直接返回错误,显然这种策略不是很适合部分业务。

如果在设置了过期时间的数据中淘汰:

  • volatile-ttl 会针对设置了过期时间的键值对,根据过期时间的先后进行删除,越早过期的越先被删除;
  • volatile-random 在设置了过期时间的键值对中,进行随机删除;
  • volatile-lru 会使用 LRU 算法筛选设置了过期时间的键值对;
  • volatile-lfu 会使用 LFU 算法选择设置了过期时间的键值对;

如果在所有数据范围内进行淘汰:

  • allkeys-random 策略,从所有键值对中随机选择并删除数据;
  • allkeys-lru 策略,使用 LRU 算法在所有数据中进行筛选;
  • allkeys-lfu 策略,使用 LFU 算法在所有数据中进行筛选;

缓存雪崩、击穿、穿透

Redis作为缓存经常会出现缓存异常的问题,其中最常见的有是那种,就是缓存雪崩、缓存击穿和缓存穿透。一旦发生这三种问题,大量的请求就会积压在数据库层,如果是高并发的业务,可能会导致数据库宕机,引发生产事故。

缓存雪崩

缓存雪崩指的是大量的应用请求无法在Redis缓存中进行处理,应用将大量请求发送到数据库,导致数据库压力骤增,一般由于两个原因导致:

  1. 缓存中有大量数据同时过期,导致大量请求无法处理;
  2. 缓存实例发生故障宕机,无法处理请求

解决问题1可以采用以下两种方式:

  • 微调过期时间:在大量数据设置相同过期时间时,可以给1~3分钟左右的时间差,避免同时过期的问题;
  • 服务降级:对核心数据可以支持访问数据库,对非核心数据返回错误信息即可,保证业务核心功能的使用;

解决问题2可以采用以下三种方式:

  • 预防:采用Redis多机的特性,保证Redis实例都有备份,能够快速进行主从切换;
  • 服务熔断:业务在调用缓存接口时,直接返回,等Redis实例恢复服务后,再允许请求发送到缓存系统;
  • 请求限流:服务端限制请求流量,允许一定量的流量直接访问DB,其他流量返回异常,避免大量请求传递到数据库;

缓存击穿

缓存击穿指的是针对某个访问非常频繁的热点数据的请求,无法在缓存中进行处理,紧接着,访问该数据的大量请求,一下子都发送到了后端数据库,导致了数据库压力激增。如果出现这个问题也很好解决,如果是非常热点的数据,就不设置过期时间,同时调整淘汰策略,保证缓存不被击穿即可。

缓存穿透

缓存穿透是指要访问的数据既不在 Redis 缓存中,也不在数据库中,导致请求在访问缓存时,发生缓存缺失,再去访问数据库时,发现数据库中也没有要访问的数据。如果应用持续有大量请求访问数据,就会同时给缓存和数据库带来巨大压力。缓存穿透一般由于两个原因导致:

  1. 业务层误操作:数据被删除,导致缓存和数据库都没有这个数据;
  2. 恶意攻击:专门访问数据库没有的数据;

针对这两种原因,可以有以下的三种方式来解决:

  • 缓存缺省值:一旦发生缓存穿透,就可以针对查询的数据在Redis中缓存一个缺省值,避免大量请求访问数据库;
  • 布隆过滤器:利用布隆过滤器进行快速检测数据是否存在,如果不存在就不要再去数据库查询了,发生缓存穿透只会查询Redis和布隆过滤器;
  • 前端请求检测:针对恶意请求,自动过滤参数不合法等情况,不访问服务与数据库;

我的博客即将同步至腾讯云+社区,邀请大家一同入驻:cloud.tencent.com/developer/s…