Redis内存淘汰策略,看这一篇就够了!

存储 存储软件 Redis
Redis作为当前最常用的开源内存数据库,性能十分高,据官方数据表示Redis读的速度是110000次/s,写的速度是81000次/s 。而且Redis支持数据持久化,众多数据结构存储,master-slave模式数据备份等多种功能。

 Redis作为当前最常用的开源内存数据库,性能十分高,据官方数据表示Redis读的速度是110000次/s,写的速度是81000次/s 。而且Redis支持数据持久化,众多数据结构存储,master-slave模式数据备份等多种功能。

但是长期将Redis作为缓存使用,难免会遇到内存空间存储瓶颈,当Redis内存超出物理内存限制时,内存数据就会与磁盘产生频繁交换,使Redis性能急剧下降。此时如何淘汰无用数据释放空间,存储新数据就变得尤为重要了。

[[261956]]

对此,Redis在生产环境中,采用配置参数maxmemory 的方式来限制内存大小。当实际存储内存超出maxmemory 参数值时,开发者们可以通过这几种方法——Redis内存淘汰策略,来决定如何腾出新空间继续支持读写工作。

那么Redis内存淘汰策略是如何工作的呢?

首先,客户端会发起需要更多内存的申请;

其次,Redis检查内存使用情况,如果实际使用内存已经超出maxmemory,Redis就会根据用户配置的淘汰策略选出无用的key;

***,确认选中数据没有问题,成功执行淘汰任务。

 

当前Redis3.0版本支持的淘汰策略有6种:

1. volatile-lru:从设置过期时间的数据集(server.db[i].expires)中挑选出最近最少使用的数据淘汰。没有设置过期时间的key不会被淘汰,这样就可以在增加内存空间的同时保证需要持久化的数据不会丢失。

2. volatile-ttl:除了淘汰机制采用LRU,策略基本上与volatile-lru相似,从设置过期时间的数据集(server.db[i].expires)中挑选将要过期的数据淘汰,ttl值越大越优先被淘汰。

3. volatile-random:从已设置过期时间的数据集(server.db[i].expires)中任意选择数据淘汰。当内存达到限制无法写入非过期时间的数据集时,可以通过该淘汰策略在主键空间中随机移除某个key。

4. allkeys-lru:从数据集(server.db[i].dict)中挑选最近最少使用的数据淘汰,该策略要淘汰的key面向的是全体key集合,而非过期的key集合。

5. allkeys-random:从数据集(server.db[i].dict)中选择任意数据淘汰。

6. no-enviction:禁止驱逐数据,也就是当内存不足以容纳新入数据时,新写入操作就会报错,请求可以继续进行,线上任务也不能持续进行,采用no-enviction策略可以保证数据不被丢失,这也是系统默认的一种淘汰策略。

上述是Redis的6种淘汰策略,关于使用这6种策略,开发者还需要根据自身系统特征,正确选择或修改驱逐。

  • 在Redis中,数据有一部分访问频率较高,其余部分访问频率较低,或者无法预测数据的使用频率时,设置allkeys-lru是比较合适的。
  • 如果所有数据访问概率大致相等时,可以选择allkeys-random。
  • 如果研发者需要通过设置不同的ttl来判断数据过期的先后顺序,此时可以选择volatile-ttl策略。
  • 如果希望一些数据能长期被保存,而一些数据可以被淘汰掉时,选择volatile-lru或volatile-random都是比较不错的。
  • 由于设置expire会消耗额外的内存,如果计划避免Redis内存在此项上的浪费,可以选用allkeys-lru 策略,这样就可以不再设置过期时间,高效利用内存了。

Redis缓存功能,是由edis.c文件中的freeMemoryIfNeeded函数实现的。如果maxmemory被设置,那么每次在执行命令钱,该函数都会被调用来判断内存是否够用、释放内存、返回错误。如果没有足够的内存程序主逻辑将会阻止设置了REDIS_COM_DENYOOM flag的命令执行,对其返回command not allowed when used memory > ‘maxmemory’的错误消息。

区分不同的淘汰策略选择不同的key,Redis淘汰策略主要分为LRU淘汰、TTL淘汰、随机淘汰三种机制。

LRU淘汰

LRU(Least recently used,最近最少使用)算法根据数据的历史访问记录来进行淘汰数据,其核心思想是“如果数据最近被访问过,那么将来被访问的几率也更高”。

在服务器配置中保存了 lru 计数器 server.lrulock,会定时(redis 定时程序 serverCorn())更新,server.lrulock 的值是根据 server.unixtime 计算出来进行排序的,然后选择最近使用时间最久的数据进行删除。另外,从 struct redisObject 中可以发现,每一个 redis 对象都会设置相应的 lru。每一次访问数据,会更新对应redisObject.lru。

在Redis中,LRU算法是一个近似算法,默认情况下,Redis会随机挑选5个键,并从中选择一个最久未使用的key进行淘汰。在配置文件中,按maxmemory-samples选项进行配置,选项配置越大,消耗时间就越长,但结构也就越精准。

 

TTL淘汰

Redis 数据集数据结构中保存了键值对过期时间的表,即 redisDb.expires。与 LRU 数据淘汰机制类似,TTL 数据淘汰机制中会先从过期时间的表中随机挑选几个键值对,取出其中 ttl ***的键值对淘汰。同样,TTL淘汰策略并不是面向所有过期时间的表中最快过期的键值对,而只是随机挑选的几个键值对。

随机淘汰

在随机淘汰的场景下获取待删除的键值对,随机找hash桶再次hash指定位置的dictEntry即可。

Redis中的淘汰机制都是几近于算法实现的,主要从性能和可靠性上做平衡,所以并不是完全可靠,所以开发者们在充分了解Redis淘汰策略之后还应在平时多主动设置或更新key的expire时间,主动删除没有价值的数据,提升Redis整体性能和空间。

责任编辑:武晓燕 来源: 云季科技
相关推荐

2020-02-18 16:20:03

Redis ANSI C语言日志型

2023-11-06 07:21:13

内存结构Jvm

2023-02-10 09:04:27

2022-06-20 09:01:23

Git插件项目

2022-08-01 11:33:09

用户分析标签策略

2021-04-08 07:37:39

队列数据结构算法

2023-09-11 08:13:03

分布式跟踪工具

2020-05-14 16:35:21

Kubernetes网络策略DNS

2020-07-03 08:21:57

Java集合框架

2018-05-22 08:24:50

PythonPyMongoMongoDB

2019-05-14 09:31:16

架构整洁软件编程范式

2024-09-23 08:00:00

消息队列MQ分布式系统

2023-10-17 08:15:28

API前后端分离

2017-03-11 22:19:09

深度学习

2022-04-07 10:39:21

反射Java安全

2023-11-18 09:30:42

模型AI

2020-10-18 07:32:06

SD-WAN网络传统广域网

2022-05-19 08:28:19

索引数据库

2020-10-21 14:12:02

Single Sign

2022-07-06 12:07:06

Python函数式编程
点赞
收藏

51CTO技术栈公众号