redis第四课-缓存淘汰策略和过期检测

Redis一般可用于两种用途:
1、被单纯作为缓存配合数据库来使用。
2、被当作持久化数据库来使用。
这次我们来讲一下redis被用做缓存时的一些可以聊的东西。
此时它有一些特点:
1、缓存数据不重要
2、不是全量数据
3、缓存应该随着访问变化
4、热数据

当既然作为缓存,那么其实我们日常在缓存中存放的不可能是全部数据,而都是一些热点数据,因为毕竟内存空间是有限的。因此随着访问的变化,应该淘汰掉冷数据
那我们说内存空间是有限的,首先需要知道,redis限定的存储数据可用内存的那个阈值是多少 ?

Maxmemory配置指令

maxmemory配置指令用于配置Redis存储数据时指定限制的内存大小。通过redis.conf可以设置该指令,或者之后使用CONFIG SET命令来进行运行时配置。
例如为了配置内存限制为100mb,以下的指令可以放在redis.conf文件中。
maxmemory 100mb
设置maxmemory为0代表没有内存限制。对于64位的系统这是个默认值,对于32位的系统默认内存限制为3GB。
当指定的内存限制大小达到时,需要选择不同的行为,也就是策略。 Redis可以仅仅对命令返回错误,这将使得内存被使用得更多,或者回收一些旧的数据来使得添加数据时可以避免内存限制。

缓存算法

在说策略之前,先说一下一般用于缓存的三种算法

FIFO算法

FIFO 算法是一种比较容易实现的算法。它的思想是先进先出(FIFO,队列),这是最简单、最公平的一种思想,即如果一个数据是最先进入的,那么可以认为在将来它被访问的可能性很小。空间满的时候,最先进入的数据会被最早置换(淘汰)掉。

LRU算法

LRU(The Least Recently Used,最近最久未使用算法)是一种常见的缓存算法,在很多分布式缓存系统(如Redis, Memcached)中都有广泛使用。
LRU算法的思想是:如果一个数据在最近一段时间没有被访问到,那么可以认为在将来它被访问的可能性也很小。因此,当空间满时,最久没有访问的数据最先被置换(淘汰)。

LFU算法

LFU(Least Frequently Used ,最近最少使用算法)也是一种常见的缓存算法。
顾名思义,LFU算法的思想是:如果一个数据在最近一段时间很少被访问到,那么可以认为在将来它被访问的可能性也很小。因此,当空间满时,最小频率访问的数据最先被淘汰。

而redis的回收策略其中就有LRU 和LFU算法的应用可供选择。

回收策略

当maxmemory限制达到的时候Redis会使用的行为由 Redis的maxmemory-policy配置指令来进行配置。
以下的策略是可用的:
noeviction:返回错误当内存限制达到并且客户端尝试执行会让更多内存被使用的命令(大部分的写入指令,但DEL和几个例外)
allkeys-lru: 尝试回收最近最久未使用的键(LRU),针对所有key,使得新添加的数据有空间存放。
volatile-lru: 尝试回收最近最久未使用的键(LRU),但仅限于在过期集合的键,使得新添加的数据有空间存放。
allkeys-lfu: 尝试回收最近最少使用的键(LFU),针对所有key,使得新添加的数据有空间存放。
volatile-lfu: 尝试回收最近最少使用的键(LFU),但仅限于在过期集合的键,使得新添加的数据有空间存放。
allkeys-random: 针对所有key,回收随机的键使得新添加的数据有空间存放。
volatile-random: 回收随机的键使得新添加的数据有空间存放,但仅限于在过期集合的键。
volatile-ttl: 回收在过期集合的键,并且优先回收存活时间(TTL)较短的键,使得新添加的数据有空间存放。
如果没有键满足回收的前提条件的话,策略volatile-lru,volatile-lfu, volatile-random以及volatile-ttl就和noeviction 差不多了。
选择正确的回收策略是非常重要的,这取决于你的应用的访问模式,不过你可以在运行时进行相关的策略调整,并且监控缓存命中率和没命中的次数,通过RedisINFO命令输出以便调优。
一般的经验规则:
使用allkeys-lru策略:当你希望你的请求符合一个幂定律分布,也就是说,你希望部分的子集元素将比其它其它元素被访问的更多。如果你不确定选择什么,这是个很好的选择。.
使用allkeys-random:如果你是循环访问,所有的键被连续的扫描,或者你希望请求分布正常(所有元素被访问的概率都差不多)。
使用volatile-ttl:如果你想要通过创建缓存对象时设置TTL值,来决定哪些对象应该被过期。

作为缓存来说noeviction作为缓存来说肯定是不用的,random过于随机,因此一般在LRU和LFU中进行选择。

REDIS过期

上面提到redis有一个“过期集合的键”,在redis中可以给1个key设置过期时间,当被认定过期后,这个key就会被列入“过期集合的键”中去。设置过期的操作如下:

  #EXPIREAT key timestamp
  #summary: Set the expiration for a key as a UNIX timestamp
  #since: 1.2.0
  #group: generic
  #设置key在哪一个时间过期
  
  #EXPIRE key seconds
  #summary: Set a key's time to live in seconds
  #since: 1.0.0
  #group: generic
  #设置key多少秒后过期
#如果不设置过期时间,永不过期
redis> SET mykey "Hello"
OK
#设置key的过期时间为10秒
redis> EXPIRE mykey 10
(integer) 1
#查看key还有几秒过期
redis> TTL mykey
(integer) 10
#从概念上讲所有改变key的值的操作都会使他清除,因此此处mykey的过期时间属性被清空,相当于永不过期。
redis> SET mykey "Hello World"
OK
redis> TTL mykey
(integer) -1
redis> 

Redis如何淘汰过期的keys

当key过期后,redis是何时检测到的呢?
Redis keys过期有两种方式:被动和主动方式。
当一些客户端尝试访问它时,key会被发现并主动的过期。
当然,这样是不够的,因为有些过期的keys,永远不会访问他们。 无论如何,这些keys应该过期,所以定时随机测试设置keys的过期时间。所有这些过期的keys将会从密钥空间删除。
具体就是Redis每秒10次做的事情:
测试随机的20个keys进行相关过期检测。
删除所有已经过期的keys。
如果有多于25%的keys过期,重复步骤1.
这是一个平凡的概率算法,基本上的假设是,我们的样本是这个密钥控件,并且我们不断重复过期检测,直到过期的keys的百分百低于25%,这意味着,在任何给定的时刻,最多会清除1/4的过期keys。
好处:稍微牺牲下内存,但是保住了redis性能为王!!!!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值