首页 > 数据库 >Redis–内存淘汰机制(涉及到过期策略)

Redis–内存淘汰机制(涉及到过期策略)

时间:2023-06-22 20:56:01浏览次数:45  
标签:策略 删除 过期 Redis redis 内存 key

这个博客的内容包括以下几个点:
1.redis内存淘汰机制
2.若有大量的key需要设置同一时间过期,一般需要注意什么?
3.过期键删除策略
4.redis如何保证数据都是热点数据

一、redis内存淘汰机制

1,概念:

内存淘汰机制:redis配置文件可以设置maxmemory,内存的最大使用量,达到限度会执行内存淘汰机制(也就是,redis用作缓存时,若内存空间用满,就会自动驱逐老的数据

2,redis中的内存淘汰机制:

Redis(五)--内存淘汰机制(涉及到过期策略)

  • 没有配置时,默认为no-evication。
  • volatile为前缀的策略:都是从已过期的数据集中进行淘汰
  • allkeys为前缀的策略:都是面向所有的key进行淘汰
  • LRU(least recently used):最近最少用到的
  • LFU(least frequently used):最不常用的
  • 他们的触发条件都是redis使用内存达到阈值时

3,淘汰策略的内部实现:

  • 客户端执行一个命令,导致redis中的数据增加,占用更多的内存
  • redis检查内存使用量,若超出maxmemory限制,根据策略清除部分key
  • 继续执行下一条命令,以此类推

在这个过程中内存的使用量会不断地达到limit值,然后超过,然后删除部分key(使用量又降到limit以下,这样循环)

若某个命令导致大量内存占用(比如通过新key保存一个很大的set),在一段时间内,可能内存的使用量会明显超过maxmemory限制。

这里涉及到一道题

若有大量的key需要设置同一时间过期,一般需要注意什么?

若有大量的key过期时间设置的过程中,到过期的那个时间点,redis可能会出现短暂的卡顿现象。一般需要在时间上加一个随机值,使得过期时间分散一些

因为这个淘汰机制中会涉及到过期键的一个删除的策略,接下来就来写一写:

二、过期键删除策略:

1,过期删除策略:

redis数据库键的过期时间都保存在过期字典中,根据系统时间和存活时间判断是否过期。

redis有三种不同的删除策略:

  • 1,定时删除:实现方式,创建定时器。(在设置键的过期时间的同时,创建一个定时器,让定时器在键的过期时间来临时,立即执行对键的删除操作)

  • 2,惰性删除:每次获取键时,检查是否过期。(键过期了就过期了,不管。每次从dict字典中按key取值时,先检查此key是否已经过期,如果过期了就删除它,并返回nil,如果没过期,就返回键值。)

  • 3,定期删除:每隔一段时间,对数据库进行一次检查,删除过期键,由算法决定删除多少过期键和检查多少数据库。

2,优缺点:

  • 1,定时删除,对内存友好(通过使用定时器,定时删除策略可以保证过期键会尽可能快地被删除,并释放过期键所占用的内存),但是对cpu很不友好(因为删除操作会占用cpu的时间,如果刚好碰上了cpu很忙的时候,比如正在做交集或排序等计算的时候,就会给cpu造成额外的压力)

  • 2,惰性删除,对cpu友好(程序只会在取出键时才对键进行过期检查,这可以保证删除过期键的操作只会在非做不可的情况下进行,并且删除的目标仅限于当前处理的键,这个策略不会在删除其他无关的过期键上花费任何CPU时间),对内存很不友好(如果一个键已经过期了,而这个键又仍然保留在数据库中,那么只要这个过期键不被删除,它所占用的内存就不会释放)

  • 3,定期删除,是两种折中,但是,如果删除太频繁,将退化为定时删除,如果删除次数太少,将退化为惰性删除

其实定期删除的难点是确定删除操作的时长和频率。

如果删除操作太频繁,或者执行的时间太长,定期删除策略就会退化成定时删除策略,以至于将CPU时间过多地消耗在删除过期键上面。
如果删除操作执行的太少,或者执行的时间太短,定期删除策略又会和惰性删除策略一样,出现浪费内存的情况。

因此,如果采用定期删除策略的话,服务器必须根据情况,合理地设置删除操作的执行时长和频率

3,Redis使用的策略:

redis使用的过期键值删除策略是:惰性删除加上定期删除,两者配合使用,服务器可以很好的在合理利用CPU时间和避免浪费内存空间之间取得平衡。

三、redis如何保证数据都是热点数据

这个为什么要放到这里来写,因为这个也涉及到过期策略这个知识点。

如何保证redis中的数据都是热点数据?redis内存数据集达到一定的大小的时候,就会实现数据淘汰策略,内存中的淘汰机制的初衷就是为了 更好的使用内存

1,先设置redis过期策略:

当设置一个key的时候,一般会给这个key设置一个过期时间(expire time),当时间到了,可以采用定期删除+惰性删除

2,但是定期删除漏掉了很多过期key,然后又没及时去做查询,也没有走惰性删除。

此时,可能会有大量的过期的key堆积在内存中,导致内存块耗尽。这时候走内存淘汰机制。(上面写的。)

3,以上保证了删除过期+留出内存空间,但又如何确保数据是最热门的数据?

其解决方案:

(1)、热点数据排序(点击次数):既然是热门数据,那么就需要有排序,使用redis中的zset数据类型是很自然的想法,数据中的某个唯一字段作为zset中的value,而点击次数作为score,记为click_zset,这样就可以选出做热门的数据,而数据直接用hashmap存储。

(2)、热点数据时间(近期访问):既然只能存比如说1w条数据且需要是热门数据,那么点击次数是一方面,时效也是一方面,如何保证?=====>可以另起一个zset,数据的字段为value,而每次点击时更新当前时间戳为其score,记为time_zset,这样就可以记录时间。在后台跑一个任务,间隔一定时间段删除两个zset中长时间没有发生点击事件的键,并删除hash数据,为产生的新数据腾出数据空间。

(3)、处理新热点数据:若有空间,则保存到自己的hashmap,并将key存到两个zset中,若没有空间时,就应该在click_zset中取出点击次数排在最前的第1w位后面的键,删除对应的hash数据,然后看这1w个score的值,然后把key放入到zset中即可。

标签:策略,删除,过期,Redis,redis,内存,key
From: https://www.cnblogs.com/javaxubo/p/17498309.html

相关文章

  • 带宽翻倍更能超!影驰HOF Classic D5-7000内存评测:超至7800MHz仍有余力
    一、前言:影驰带来DDR5-7000内存C32时序、1.45V规格亮眼DDR5内存诞生初期被大众吐槽时序高、价格高,甚至表现不如高频DDR4内存,极大地阻碍了其普及,所以Intel12/13代酷睿也同时保留了对DDR4的支持。不过,时隔仅仅一年半,DDR5的这些问题就已经解决得差不多了。现在高频DDR5内存遍地开......
  • Redis 分布式锁
    为什么使用分布式锁场景在分布式系统中,java中synchronized锁只是JVM级别的,也就是进程级别。因此,当同一个服务,启动多次出现多个节点时,在不同进程中,相同的同步代码块使用 synchronized,并不能达到想要的同步效果,也就是这个关键字管不到别的进程。此时,前端如果出现高......
  • django中使用redis
    django中使用redis方法1,通用安装redis#pipinstallredis#1写一个连接池 importredis.ConnectionPool(host='xx.xx.xx.xx',port=6379,password='xxx',max_connections=1000)#2在使用地方导入即可 conn=redis.Redis(connection_pool=pool)conn.incr(�......
  • redis之列表和其他操作
    redis之列表1lpush(name,values)2rpush(name,values)表示从右向左操作3lpushx(name,value)4rpushx(name,value)表示从右向左操作5llen(name)6linsert(name,where,refvalue,value))7r.lset(name,index,value)8r.lrem(name,value,num)9lpop(name)10......
  • redis使用事务
    redis管道#事务--》四大特性-原子性-一致性-隔离性-持久性#redis使用事务importrediscon=redis.Redis()p=con.pipeline(transacction=True)#使用事务p.multi()开启事务#任务p.execute()p.close()......
  • localStorage如何设置过期时间 (如何封装自定义localStorage)
    1、创建Storage类定义对应的getsetremoveclearapi通过set函数添加过期时间参数来实现过期时间的记录设置存储时存储当前值和过期时间get取值的时候先验证当前值是否存在以及时间是否大于过期时间如果存在且不大于过期时间既可返回对应的值否则返回空classStorage......
  • redis数据类型和字符串操作
    redis数据类型1字符串===》做缓存,做计数器''' setkeyvalue getkey msetk1v1k2v2... mgetk1k2... setexkeyexpvalue incrbykeyincrement'''2列表===》消息队列''' rpushkeyvalue1value2... lpushkeyvalue1valu......
  • redis简单介绍和使用
    redis安装"""1、官网下载:安装包或是绿色面安装2、安装并配置环境变量#官网:https://redis.io/ -下载完是源代码:c语言源码:https://redis.io/download/#redis-stack-downloads-最稳定:6.x-最新7.x#中文网:http://redis.cn/download.html -上面最新只到5.x......
  • hiredis的同步模式和异步模式
    1.什么是hiredisHiredis是一个C语言编写的Redis客户端库,用于与Redis数据库进行交互。它提供了一个简洁而高效的接口,使开发人员可以方便地在自己的C/C++项目中使用Redis。Hiredis是一个开源项目,可从其官方GitHub仓库获取源代码,并在符合BSD许可证的条件下使用和分......
  • Android内存优化分析总结,这一篇就够了
    一、内存优化概念1.1为什么要做内存优化?内存优化一直是一个很重要但却缺乏关注的点,内存作为程序运行最重要的资源之一,需要运行过程中做到合理的资源分配与回收,不合理的内存占用轻则使得用户应用程序运行卡顿、ANR、黑屏,重则导致用户应用程序发生OOM(outofmemory)崩溃。在你认真跟......