Redis的数据淘汰策略及相关注意事项

时间:2021-09-25 10:28:58

Redis 是完全开源免费的,遵守BSD协议,是一个高性能的key-value数据库。提供数据持久化,更多的数据结构存储,master-slave模式的数据备份。

Redis性能极高 – 来自官方文档的数据:Redis能读的速度是110000次/s,写的速度是81000次/s 。

将Redis作为缓存使用时,尤其是在数据量很大,内存空间有限的情况下,考虑如何淘汰掉旧数据释放空间存储新数据就更为重要了。


参数设置

Redis中存在一个参数用来设定内存使用上限,这个参数是maxmemory,可以在redis.conf中设置redis内存使用的最大值,当redis使用内存达到最大值时(如何知道已达到最大值?),redis会根据配置文件中的策略选取要删除的key,并删除这些key-value的值。若根据配置的策略,没有符合策略的key,也就是说内存已经容不下新的key-value了,但此时有不能删除key,那么这时候写的话,将会出现写错误。


我们可以通过配置redis.conf中的maxmemory这个值来开启内存淘汰功能,至于这个值有什么意义,我们可以通过了解内存淘汰的过程来理解它的意义:

1. 客户端发起了需要申请更多内存的命令(如set)。



2. Redis检查内存使用情况,如果已使用的内存大于maxmemory则开始根据用户配置的不同淘汰策略来淘汰内存(key),从而换取一定的内存。



3. 如果上面都没问题,则这个命令执行成功。

最大内存参数设置

若maxmemory参数设置为0,则分两种情况:

*在64位系统上,表示没有限制。

*在32为系统上,是3G,redis官方文档的说法是,32位系统最大内存是4G,预留1G给系统。而且策略会自动设置为noeviction。

也就是说在32位系统上,若maxmemory设置为0,则默认是3G,当到达3G,再往reidis中写入时,则会报错。

淘汰策略介绍

Redis在已使用内存达到设定的上限时,提供了6种数据淘汰策略(也就是maxmemory-policy可能的值):


volatile-lru:从已设置过期时间的数据集(server.db[i].expires)中挑选最近最少使用 的数据淘汰
volatile-ttl:从已设置过期时间的数据集(server.db[i].expires)中挑选将要过期的数 据淘汰
volatile-random:从已设置过期时间的数据集(server.db[i].expires)中任意选择数据 淘汰
allkeys-lru:从数据集(server.db[i].dict)中挑选最近最少使用的数据淘汰
allkeys-random:从数据集(server.db[i].dict)中任意选择数据淘汰
no-enviction(驱逐):禁止驱逐数据

需要注意以下几点:

1、maxmemory-policy同样可以在运行时设置,用户可以根据内存的使用情况动态的修改淘汰策略。

2、当redis中的数据有一部分访问频率比较高,另外一部分访问频率较低时,设置allkeys-lru比较合适。或者无法预测数据的使用频率时,allkeys-lru也是不错的选择。

3、如果你需要循环或者扫描连续数据时,换种说法就是数据的访问概率大致相等时,allkeys-random是不错的选择。

4、当你想通过设置不同的ttl来控制数据过期的先后顺序时,你可以设置为volatile-ttl。

5、当你希望一些数据常驻内存,另外一些数据可以被替换掉时,就请用volatile-lru或volatile-random吧。

6、另外,数据的过期时间是存储在另外一个哈希表中的,因此要耗费更多的内存空间,而allkeys-lru并不需要数据设置过期时间,因此对内存的利用率更高。

7、volatile-lru, volatile-random 和 volatile-ttl 在没有数据满足被淘汰的条件时,会和noeviction一样返回错误。


何时触发淘汰数据的动作

1、一个客户端执行指令,导致数据的增加时。

2、Redis检测到内存的使用已经达到上限。

3、Redis自身执行指令时,等等


注意:

Redis为了避免反复触发淘汰策略,每次会淘汰掉一批数据。

当Redis指令产生数据比较大时,淘汰掉的数据量也相应也比较大。

为了节省内存,LRU的策略并不是严格执行的,Redis是在整体中随机抽样取出一小部分数据,在这部分数据中严格执行LRU策略,在Redis3.0以后的版本对此算法做了改进,但仍然也是近似的LRU的策略,只是离真正的LRU更近了。

另外用户可以动态的设定随机抽取的样本数,例如:

maxmemory-samples 5


更多的选择

从Redis4.0开始,Redis增加了LFU的淘汰策略,即最不频繁使用策略,这个策略的好处是能够将最频繁使用的数据留在数据库里,而将最不常使用的数据淘汰掉。

注:

LFU是Less Frequently Used的缩写,译为最不频繁使用。


总结

Redis为了提高内存的使用效率,提供了6种数据淘汰策略,这些策略可以动态的设定,在内存使用空间超过设定的内存上限时触发执行。为了节省内存Redis使用的LRU策略实际上是一种近似的LRU。

Redis的数据淘汰策略及相关注意事项