一、内存淘汰策略重要性

我们都知道redis的性能很高,最主要的原因之一就是redis的数据都在内存中放着,我们在从redis中获取数据或者更新redis中的数据时,都是操作的内存中的数据。而当内存被占满了之后怎么办呢?这时就有必要将一些数据清理掉,以便新的数据能够放到redis中。而清理掉哪些数据?保留哪些数据?什么时候清理?如何配置这些策略?这些就是接下来要研究的内容。

二、Key值过期策略

Redis中可以为key设置过期时间,当到达过期时间后,就需要将这个key删除掉。Redis中提供了两种过期删除策略:惰性删除和定期删除。

定期删除

Redis会将每个设置了过期时间的key放入到一个独立的字典中,以后会定期遍历这个字典来删除到期的key。Redis默认每秒进行10次过期扫描(100ms一次,可以通过修改配置文件redis.conf 的 hz 选项来调整这个次数),但这个扫描并不会扫描过期字典中所有的key,而是通过一种贪心策略来随机筛选删除key,步骤如下:

从过期字典中随机选出20个key;

删除这20个key中已经过期的key;

如果过期的key的比例超过了1/4,那就重复从步骤1开始执行。

之所以采用这种扫描策略,还是为了性能考虑。假如过期字典中有数百万个key,每隔100ms就扫描一次这数百万个key,会给CPU造成很大的负荷,所以,就选择了这种随机筛选部分key,然后按照过期比例来判断是否需要重复执行筛选过期的动作。

正是由于使用了这种扫描策略,定期删除可能会造成很多已经过期的key无法及时删除,所以就有了接下来的惰性删除策略。

惰性删除

所谓惰性删除就是在客户端访问这个key的时候,Redis对key的过期时间进行检查,如果过期了就立即删除,然后返回null。

不管是定期删除还是惰性删除,都是一种不完全精确的删除策略,始终还是会存在已经过期的key无法被删除的场景。而且这两种过期策略都是只针对设置了过期时间的key,不适用于没有设置过期时间的key的淘汰,所以,Redis还提供了内存淘汰策略,用来筛选淘汰指定的key。

三、内存淘汰策略

redis提供的内存淘汰策略中有一部分是基于LRU和LFU实现的,这两种算法实现的,如果对这两种算法不太熟悉,可以先学习下这两种算法

Redis目前共提供了8种内存淘汰策略,其中有两种基于LFU算法的策略是Redis4.0版本之后增加的。接下来让我们一起了解下这8种淘汰策略:

noeviction:只返回错误,不会删除任何key。该策略是Redis的默认淘汰策略,一般不会选用。

volatile-ttl:将设置了过期时间的key中即将过期(剩余存活时间最短)的key删除掉。

volatile-random:在设置了过期时间的key中,随机删除某个key。

allkeys-random:从所有key中随机删除某个key。

volatile-lru:基于LRU算法,从设置了过期时间的key中,删除掉最近最少使用的key。

allkeys-lru:基于LRU算法,从所有key中,删除掉最近最少使用的key。该策略是最常使用的策略。

volatile-lfu:基于LFU算法,从设置了过期时间的key中,删除掉最不经常使用(使用次数最少)的key。

allkeys-lfu:基于LFU算法,从所有key中,删除掉最不经常使用(使用次数最少)的key。

需要注意的是,Redis中的LRU算法并没有严格按照常规的LRU算法的方式实现,而是基于LRU算法的思想做了自己的优化。我们知道,实现LRU算法时,需要将所有的数据按照访问时间距离当前时间的长短排序放到一个双向链表中,基于这个链表实现数据的淘汰。但Redis中存储的数据量是非常庞大的,如果要基于常规的LRU算法,就需要把所有的key全部放到这个双向链表中,这样就会导致这个链表非常非常大,不止需要提供更多的内存来存放这个链表结构,而且操作这么庞大的链表的性能也是比较差的。

所以,Redis中的LRU算法是这样实现的:首先定义一个淘汰池,这个淘汰池是一个数组(大小为16),然后触发淘汰时会根据配置的淘汰策略,先从符合条件的key中随机采样选出5(可在配置文件中配置)个key,然后将这5个key按照空闲时间排序后放到淘汰池中,每次采样之后更新这个淘汰池,让这个淘汰池里保留的总是那些随机采样出的key中空闲时间最长的那部分key。需要删除key时,只需将淘汰池中空闲时间最长的key删掉即可。

为了方便理解它的思想,我画了一个图:

三、Redis内存淘汰策略配置

学习了这8种内存淘汰策略之后,Redis要什么时候会触发执行这些淘汰策略呢?又要怎么指定使用哪一种淘汰策略呢?这就要去Redis的配置文件中进行配置了

配置redis最大内存

在配置文件redis.conf 中,可以通过参数 maxmemory 来设定最大内存:

当数据内存达到 maxmemory 时,便会触发redis的内存淘汰策略。该参数通常设定为其物理内存的四分之三。

配置redis淘汰策略

在配置文件redis.conf 中,通过设置 maxmemory-policy 来指定使用哪种内存淘汰策略:

配置最大采样数量

上文在讲Redis的LRU算法的时候,提到了Redis每次会随机选择5个key放入淘汰池中,这个5的数量就是在redis.conf配置文件中通过 maxmemory-samples 选项配置的:

Redis内存淘汰策略的更多相关文章

  1. Redis数据结构和使用场景,redis内存淘汰策略

    什么样的数据适合放入Redis? sql执行耗时特别久,且结果不频繁变动的数据,适合放入Redis. Redis是单线程的,为什么会这么快? 纯内存操作 单线程操作,避免频繁的上下文切换 采用了非阻塞 ...

  2. LRU工程实现源码(一):Redis 内存淘汰策略

    目录 内存淘汰是什么?什么时候内存淘汰 内存淘汰策略 Redis中的LRU淘汰算法 源码剖析 第一步:什么时候开始淘汰key 配置读取 检查时机 getMaxmemoryState 第二步:淘汰哪些k ...

  3. Redis详解(十一)------ 过期删除策略和内存淘汰策略

    在介绍这篇文章之前,我们先来看如下几个问题: ①.如何设置Redis键的过期时间? ②.设置完一个键的过期时间后,到了这个时间,这个键还能获取到么?假如获取不到那这个键还占据着内存吗? ③.如何设置R ...

  4. 面试官:Redis 过期删除策略和内存淘汰策略有什么区别?

    作者:小林coding 计算机八股文网站:https://xiaolincoding.com 大家好,我是小林. Redis 的「内存淘汰策略」和「过期删除策略」,很多小伙伴容易混淆,这两个机制虽然都 ...

  5. Redis系列11:内存淘汰策略

    Redis系列1:深刻理解高性能Redis的本质 Redis系列2:数据持久化提高可用性 Redis系列3:高可用之主从架构 Redis系列4:高可用之Sentinel(哨兵模式) Redis系列5: ...

  6. Redis的过期策略和内存淘汰策略(转)

    Redis的过期策略 我们都知道,Redis是key-value数据库,我们可以设置Redis中缓存的key的过期时间.Redis的过期策略就是指当Redis中缓存的key过期了,Redis如何处理. ...

  7. Redis的过期策略和内存淘汰策略

    Redis的过期策略:通常有三种,Redis中同时使用惰性过期和定期过期两种过期策略组合. 定时过期:每个设置过期时间的key都需要创建一个定时器,到过期时间就会立即清除.该策略可以立即清除过期的数据 ...

  8. redis键的过期和内存淘汰策略

    键的过期时间 设置过期时间 Redis可以为存储在数据库中的值设置过期时间,作为一个缓存数据库,这个特性是很有帮助的.我们项目中的token或其他登录信息,尤其是短信验证码都是有时间限制的. 按照传统 ...

  9. Redis的内存淘汰策略

    Redis占用内存大小 我们知道Redis是基于内存的key-value数据库,因为系统的内存大小有限,所以我们在使用Redis的时候可以配置Redis能使用的最大的内存大小. 1.通过配置文件配置 ...

  10. Redis系列之-—内存淘汰策略(笔记)

    一.Redis ---获取设置的Redis能使用的最大内存大小 []> config get maxmemory ) "maxmemory" ) " --获取当前内 ...

随机推荐

  1. Burp Suite入门

    Burpsuite Burp Suite是一个Web应用程序集成攻击平台,它包含了一系列burp工具,这些工具之间有大量接口可以互相通信,这样设计的目的是为了促进和提高整个攻击的效率.平台中所有工具共 ...

  2. RabbitMQ的全面简述讲解

    **转载自微信公众号:楼仔** 常见的消息队列很多,主要包括 RabbitMQ.Kafka.RocketMQ 和 ActiveMQ,这篇文章只讲 RabbitMQ,先讲原理,后搞实战. 思维导图: 1 ...

  3. [2013年NOIP提高组] 积木大赛

    春春幼儿园举办了一年一度的"积木大赛".今年比赛的内容是搭建一座宽度为n的大厦,大厦可以看成由n块宽度为1的积木组成,第i块积木的最终高度需要是hi. 在搭建开始之前,没有任何积木 ...

  4. Map 使用

    1.替换map中的某个key Map<String,Object> map = new HashMap<>(); map.put("新key",map.re ...

  5. CGTime CMTimeRange CMTimeMapping 小结

    CMTime CMTimeRange CMTimeMapping 在使用 AVFoundation 框架处理多媒体资源时,通常会用到一些在 CoreMedia 框架中定义的结构体, 这里对其中描述时间 ...

  6. FATAL Exited too quickly (process log may have details)的解决方案

    作为一个混混的开发,不会啥容器操作.所以一般都是用supervisor来管理一些运行的进程 用了一段时间还是比较好用的,这个软件也是用的Python开发. 但在使用的过程中,status时会出现 FA ...

  7. Appium+Python UI自动化框架

    import datetimefrom appium.webdriver.common.touch_action import TouchActionfrom appium import webdri ...

  8. 20200924--图像相似度(奥赛一本通P92 5多维数组)

    给出两幅相同大小的黑白图像(用0-1矩阵)表示,求它们的相似度.说明:若两幅图像在相同位置上的像素点颜色相同,则称它们在该位置具有相同的像素点.两幅图像的相似度定义为相同像素点数占总像素点数的百分比. ...

  9. https://计算机三级

    计算机三级内容:"网络技术","数据库技术","软件测试技术","信息安全技术","嵌入式系统开发技术&quo ...

  10. 《Linux就该这么学》这本书写得真好,我很喜欢。

    本书是由全国多名红帽架构师(RHCA)基于最新Linux系统共同编写的高质量Linux技术自学教程,极其适合用于Linux技术入门教程或讲课辅助教材,目前是国内最值得去读的Linux教材,也是最有价值 ...