别再问我Redis内存满了该怎么办了

概述

Redis的文章,我以前写过一篇关于Redis的缓存的三大问题,累计阅读也快800了,对于还只有3k左右的粉丝量,可以达到这个阅读量,已是比较难了。web

这说明那篇文章写的还过得去,收到不少人的阅读确定,感兴趣的看一下[]。面试

三大缓存问题只是Redis的其中的一小部分的知识点,想要深刻学习Redis还要学习比较多的知识点。redis

那么今天就带来了一个面试常问的一个问题:假如你的Redis内存满了怎么办? 长期的把Redis做为缓存使用,总有一天会存满的时候对吧。算法

这个面试题不慌呀,在Redis中有配置参数maxmemory能够设置Redis内存的大小缓存

在Redis的配置文件redis.conf文件中,配置maxmemory的大小参数以下所示: 实际生产中确定不是100mb的大小哈,不要给误导了,这里我只是让你们认识这个参数,通常小的公司都是设置为3G左右的大小。dom

除了在配置文件中配置生效外,还能够经过命令行参数的形式,进行配置,具体的配置命令行以下所示:编辑器

//获取maxmemory配置参数的大小
127.0.0.1:6379> config get maxmemory
//设置maxmemory参数为100mb
127.0.0.1:6379> config set maxmemory 100mb
复制代码

假若实际的存储中超出了Redis的配置参数的大小时,Redis中有淘汰策略,把须要淘汰的key给淘汰掉,整理出干净的一块内存给新的key值使用学习

接下来咱们就详细的聊一聊Redis中的淘汰策略,而且深刻的理解每一个淘汰策略的原理和应用的场景。优化

淘汰策略

Redis提供了6种的淘汰策略,其中默认的是noeviction,这6中淘汰策略以下:url

  1. noeviction( 默认策略):如果内存的大小达到阀值的时候,全部申请内存的指令都会报错。
  2. allkeys-lru:全部key都是使用 LRU算法进行淘汰。
  3. volatile-lru:全部 设置了过时时间的key使用LRU算法进行淘汰。
  4. allkeys-random:全部的key使用 随机淘汰的方式进行淘汰。
  5. volatile-random:全部 设置了过时时间的key使用随机淘汰的方式进行淘汰。
  6. volatile-ttl:全部设置了过时时间的key 根据过时时间进行淘汰,越早过时就越快被淘汰

假如在Redis中的数据有一部分是热点数据,而剩下的数据是冷门数据,或者咱们不太清楚咱们应用的缓存访问分布情况,这时可使用allkeys-lru

假如全部的数据访问的频率大概同样,就可使用allkeys-random的淘汰策略。

假如要配置具体的淘汰策略,能够在redis.conf配置文件中配置,具体配置以下所示: 这只须要把注释给打开就能够,而且配置指定的策略方式,另外一种的配置方式就是命令的方式进行配置,具体的执行命令以下所示:

// 获取maxmemory-policy配置
127.0.0.1:6379> config get maxmemory-policy
// 设置maxmemory-policy配置为allkeys-lru
127.0.0.1:6379> config set maxmemory-policy allkeys-lru
复制代码

在介绍6种的淘汰策略方式的时候,说到了LRU算法,那么什么是LRU算法呢?

LRU算法

LRU(Least Recently Used)即表示最近最少使用,也就是在最近的时间内最少被访问的key,算法根据数据的历史访问记录来进行淘汰数据。

它的核心的思想就是:假如一个key值在最近不多被使用到,那么在未来也不多会被访问

实际上Redis实现的LRU并非真正的LRU算法,也就是名义上咱们使用LRU算法淘汰键,可是实际上被淘汰的键并不必定是真正的最久没用的。

Redis使用的是近似的LRU算法,经过随机采集法淘汰key,每次都会随机选出5个key,而后淘汰里面最近最少使用的key

这里的5个key只是默认的个数,具体的个数也能够在配置文件中进行配置,在配置文件中的配置以下图所示: 当近似LRU算法取值越大的时候就会越接近真实的LRU算法,能够这样理解,由于取值越大那么获取的数据就越全,淘汰中的数据的就越接近最近最少使用的数据

那么为了实现根据时间实现LRU算法,Redis必须为每一个key中额外的增长一个内存空间用于存储每一个key的时间,大小是3字节。

在Redis 3.0中对近似的LRU算法作了一些优化,Redis中会维护大小是16的一个候选池的内存。

当第一次随机选取的采样数据,数据都会被放进候选池中,而且候选池中的数据会根据时间进行排序。

当第二次之后选取的数据,只有小于候选池内的最小时间的才会被放进候选池中。

当某一时刻候选池的数据满了,那么时间最大的key就会被挤出候选池。当执行淘汰时,直接从候选池中选取最近访问时间最小的key进行淘汰。

这样作的目的就是选取出最近似符合最近最少被访问的key值,可以正确的淘汰key值,由于随机选取的样本中的最小时间可能不是真正意义上的最小时间。

可是LRU算法有一个弊端:就是假如一个key值在之前都没有被访问到,然而最近一次被访问到了,那么就会认为它是热点数据,不会被淘汰。

然而有些数据之前常常被访问到,只是最近的时间内没有被访问到,这样就致使这些数据极可能被淘汰掉,这样一来就会出现误判而淘汰热点数据。

因而在Redis 4.0的时候除了LRU算法,新加了一种LFU算法,那么什么是LFU算法算法呢?

LFU算法

LFU(Least Frequently Used)即表示最近频繁被使用,也就是最近的时间段内,频繁被访问的key,它以最近的时间段的被访问次数的频率做为一种判断标准。

它的核心思想就是:根据key最近被访问的频率进行淘汰,比较少被访问的key优先淘汰,反之则优先保留。

LFU算法反映了一个key的热度状况,不会由于LRU算法的偶尔一次被访问被认为是热点数据。

在LFU算法中支持volatile-lfu策略和allkeys-lfu策略。

以上介绍了Redis的6种淘汰策略,这6种淘汰策略旨在告诉咱们怎么作,可是何时作?这个还没说,下面咱们就来详细的了解Redis何时执行淘汰策略。

删除过时键策略

在Redis种有三种删除的操做此策略,分别是:

  1. 定时删除:建立一个定时器,定时的执行对key的删除操做。
  2. 惰性删除:每次只有再访问key的时候,才会检查key的过时时间,如果已通过期了就执行删除。
  3. 按期删除:每隔一段时间,就会检查删除掉过时的key。

定时删除对于内存来讲是友好的,定时清理出干净的空间,可是对于cpu来讲并非友好的,程序须要维护一个定时器,这就会占用cpu资源。

惰性的删除对于cpu来讲是友好的,cpu不须要维护其它额外的操做,可是对于内存来讲是不友好的,由于要是有些key一直没有被访问到,就会一直占用着内存。

按期删除是上面两种方案的折中方案**,每隔一段时间删除过时的key,也就是根据具体的业务,合理的取一个时间按期的删除key**。

经过最合理控制删除的时间间隔来删除key,减少对cpu的资源的占用消耗,使删除操做合理化。

RDB和AOF 的淘汰处理

在Redis中持久化的方式有两种RDBAOF,具体这两种详细的持久化介绍,能够参考这一篇文章[]。

在RDB中是以快照的形式获取内存中某一时间点的数据副本,在建立RDB文件的时候能够经过savebgsave命令执行建立RDB文件。

这两个命令都不会把过时的key保存到RDB文件中,这样也能达到删除过时key的效果。

当在启动Redis载入RDB文件的时候,Master不会把过时的key载入,而Slave会把过时的key载入。

在AOF模式下,Redis提供了Rewite的优化措施,执行的命令分别是REWRITEAOFBGREWRITEAOF这两个命令都不会把过时的key写入到AOF文件中,也能删除过时key

相关文章
相关标签/搜索