Redis:缓存淘汰策略

本篇文章是基于极客时间蒋德钧老师的redis核心技术与实战redis缓存篇做的学习笔记


为什么需要做缓存?

  • 提高请求效率,数据库操作效率不良,请求效率也不良
  • 减轻数据库压力,在高并发系统当中,大量请求直接压到数据库层会给数据库造成压力,请求过大可能造成数据库崩溃

redis提供了高效的数据存储功能,所以被广泛的应用到了缓存场景当中,既能有效地提升业务应⽤的 响应速度,还可以避免把⾼并发⼤压⼒的请求发送到数据库层。
redis是将数据缓存在内存当中,内存与外存的成本不一样,所以当然不能将所有数据缓存在redis当中,这就可能存在缓存满了的问题。

具体来说,我们需要掌握以下几点

  1. 缓存特征?
  2. redis缓存是怎么工作的?
  3. redis缓存满了怎么办?有哪些替换策略?
  4. 为什么会有缓存⼀致性、缓存穿透、缓存雪崩、缓存击穿等异常,该如何应对?
  5. Redis的内存毕竟有限,如果⽤快速的固态硬盘来保存数据,可以增加缓存的数据量,那么,Redis缓存可 以使⽤快速固态硬盘吗?

缓存特征

  1. 缓存一定是一个快速子系统,数据存在缓存当中,能够避免每次从慢系统中读取数据,数据库为慢系统,redis为快系统,redis的操作效率多为数据库操作效率的十倍以上。
  2. 缓存系统的容量大小总是小于后端慢速系统的,不可能把所有数据放到缓存系统中,redis具备缓存淘汰策略,所以也是redis适合做缓存的一个特征。

Redis处理缓存请求

缓存系统中都是先查redis,后查数据库
两个关键术语
缓存命中:读取redis,查询到缓存
缓存缺失:读取redis,查询缓存为空

redis称为旁路缓存,读取缓存、读取数据库和更新缓存的操作都需要在应用程序中完成

缓存类型

redis是不会区分缓存类型的,由于redis作为缓存所有的操作都是应用程序完成的,所以为了更好的在不同的情况下处理数据,可以人为的思考该缓存为那种类型,执行不同的逻辑

只读缓存:最新数据在数据库

  • 查询数据:缓存命中,返回数据,缓存缺失查询数据库
  • 修改数据:所有的请求,直接发往数据库修改数据库,修改完,缓存存在,删除缓存。再次读取数据,缓存缺失,读取数据库,重新缓存
    只读缓存修改数据流程

读写缓存:最新数据在redis
所有读写请求都会发送给缓存,直接在redis中增删改操作。因为最新数据在redis当中,容易出现数据丢失,所以根据业务应用对数据可靠性和缓存性能的不同要求,有同步直写和异步写回两种策略。

同步直写:写请求发给缓存的同时,也会发给后端数据库进行处理,等到缓存和数据库都写完数据,才返回。

  • 优点:缓存系统发生故障,数据库依旧是最新数据,提供了数据可靠性。
  • 缺点:降低缓存的访问性能。

异步写回:所有请求先在缓存中执行,缓存中执行完直接返回。等到被修改过的缓存在缓存中淘汰出来时,缓存将他们写回数据库(redis缓存淘汰机制并不会主动写回数据库,所以选择异步写回的时候需要在客户端完成写回操作)。

  • 优点:响应延迟低,redis缓存操作速度快
  • 缺点:缓存系统出现故障,容易出现数据丢失
    读写缓存写回策略
    缓存类型选择
  • 对写请求进行加速,选择读写缓存
  • 写请求少或者提升请求响应速度,选择只读缓存

缓存淘汰策略

8中淘汰策略 (4.0之前六种,4.0之后八种)
在这里插入图片描述
内存使用超过maxmemory值,会根据配置执行相关淘汰策略

  1. noevction:不淘汰。redis不再提供服务,不再处理请求,直接返回错误。
  2. volatile-random:设置了过期时间随机淘汰。
  3. volatile-ttl:设置了过期时间,越早过期的越先被淘汰。
  4. volatile-lru:使用LRU算法(最近最少使用原则)赛选设置了过期时间的键值对
  5. volatile-lfu:使用LFU算法赛选设置了过期时间的键值对
  6. allkeys-random:所有键值对中随机选择淘汰。
  7. allkeys-lru:使⽤LRU算法在所有数据中进⾏筛选。
  8. allkeys-lfu:使⽤LFU算法在所有数据中进⾏筛选

如何处理淘汰的数据

前面提到了缓存的写回策略,只有读写缓存的异步写回需要写回数据库。
由于redis淘汰缓存是不会把他们写回数据库的,所以没有办法实现淘汰数据写回数据库这个操作,还是采用同步直写的方式写回数据库。

LRU算法

lru算法最近最少使用的原则来筛选数据,最不常用的数据会被筛选出来。

lru算法是以链表方式组织所有数据的,最近被访问的元素会被放到链表的头,最久未被访问的数据会被放到链表的尾,当有数据插入时,内存不够,会将新数据插入到链表头,删除链表尾数据。
缺点:
链表产生额外开销
当链表中大量数据被访问时,带来很多链表移动操作,会很耗时,降低redis缓存性能。

redis中lru简化

redis提供一个配置参数maxmemory-samples来配置redis选出的淘汰缓存个数组成链表。
redis会默认记录每个数据的最近一次访问的时间戳存放在键值对lru字段记录。

执行以下命令,redis会选出100个数据当候选数据集

config set maxmemory-samples 100

当内存不够有新的数据加入时,redis会筛选能进入候选集合的数据的lru字段的值必须小于候选集合中的最小的lru值,当有新数据进入达到maxmenory-samples时会将最小的lru数据淘汰出去
优点:这样没用每次维护一个大链表,也不用每次访问数据的时候都移动链表项,提升了缓存性能。

lfu算法解决缓存污染

LFU缓存策略是在LRU策略的基础商,为每个数据增加了一个计数器,来统计这个数据的访问次数。当使用LFU算法筛选出淘汰数据时,首先会根据数据的访问次数进行筛选,把访问次数最低的数据淘汰出缓存。如果两个数据访问次数相同,会根据两个数据的访问时效性,把距离上一次访问时间更久的数据淘汰出缓存。

使用哪种缓存淘汰策略?

业务数据有明显的冷热之分:allkeys-lru算法
无冷热之分:allkeys-random算法
有置顶需求(永远不需要删除):使用volatile-lru算法,并且不设置过期时间(永远不会过期)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值