redis内存数据过期数据问题

redis服务器将所有数据库都保存在服务器状态redis.h/rediserver结构的db数组中,db数组中的每个项是redis.h/redisDB结构

每个redisDB代表一数据库,初始化服务器时,会根据服务器状态的dbnum属性创建多少个数据库。
dbnum属性由database选项决定,默认是16.

默认情况下,redis 客户端的目标数据库为 0 号数据库,但客户端可以通过执行 select 命令来切换目标数据库。切到2号数据库进行的操作。
在这里插入图片描述
在服务器内部,客户端redisClient结构中db记录了客户端当前的数据库,redisClient结构的db指针指向redisServer的db的一个元素,而被指向的元素就是客户端的数据库。

select命令的实现原理:
通过修改redisClient.db指针,让它指向服务器中的不同数据库,从而实现目标数据库切换功能。

谨慎处理多数据程序:
因为redis没有可以返回客户端目标数据库的命令,即使redis-cli客户端会提示当前所使用的目标数据库,若在其他客户端执行redis命令,没有显示目标数据库的号码,多次切数据库后,忘记使用的数据库,避免误操作,在执行flushdb这样的命令,最好先执行select命令,明显知道具体数据库。

redisDb结构中还有一个dict字典,里面保存了数据库中的所有键值对,dict字典叫键空间。
键空间的键就是数据库的键,每个键都是字符串对象。
键空间的值就是数据库的值,每个值可以是字符串、列表、哈希、集合、有序集合。

添加、删除、更新键/值其实就是在键空间中添加、删除、更新键以及键的值。

读写对键空间的维护操作:
读取一个键后(读和写操作都要对键进行读取),服务器会根据键是否存在来更新服务器的键空间命中(hit)次数或键空间不命中(miss)次数
在这里插入图片描述
读取一个键后,服务器会更新键的LRU最后一次使用时间,这个值可以计算键的闲置时间,使用OBJECT idletime可以查看键的闲置时间。
![在这里插入图片描述]https://img-blog.csdnimg.cn/f7ab4c9d547a41db98c55ab5f0cad2d9.p在这里插入图片描述
ng)

服务器读取键时发现该键过期,会先删除过期键。

服务器保存键的生存时间和过期时间方法:
有四个命令设置键的生存空间或过期时间(expire,pexpire,expireat,pexireat),虽然是四个,其实都是使用pexireat命令来实现。

redisDb结构中有一个expires字典保存数据库中所有数据库的过期时间,我们称这个字典为过期字典。
expires的键是一个指针,指向键空间的某个键对象(数据库键)。
expires的值是一个long long类型的整数,这个整数保存了键所指向的数据库键的过期时间——一个毫秒精度的时间戳。

如果一个键过期了,什么时候会被删除呢?
定时删除(主动删除策略):在设置键的过期时间的同时,创建一个定时器,让定时器在键的过期时间来临时,立即执行对键的删除操作。优点:内存友好,缺点:cpu不友好。
惰性删除(被动删除策略):放任键过期不管,但是每次从键空间中获取键时,都检查取得的键是否过期,如果过期的话,就删除该键;如果没有过期,就返回该键。
在执行所有读写数据库的命令之前,调用expireIFNeeded函数。判断键过期,就删除键,没过期,expireIFNeeded函数不做动作。优点:对cpu友好,对内存不友好。内存泄漏,无用的垃圾数据占用了大量的内存。大量日志积压在数据库中,用户以为日志已经删除,实际还存在,键占用的内存没释放,造成后果很严重。
定期删除(主动删除策略):每隔一段时间,程序就对数据库进行一次检查,删除里面的过期键。至于要删除多少过期键,以及要检查多少个数据库,则由算法决定。

定期删除是比较折中的方法,
是每隔一段时间执行一次删除过期键操作,是通过限制删除操作的执行时长和频率减少删除对cpu时间的影响。
定期删除难点是确认删除过期键的频率和删除操作的执行时长。服务器必须根据情况,合理地设置删除操作的执行时长和执行频率。
由activeExpireCycle函数实现,规定的时间内,分多次遍历服务器中的各个数据库,从数据库的expires字典中随机检查一部分键的过期时间,并删除其中的过期键。

当新数据进入redis中,如果内存不足怎么办?
在执行命令前,会调用freeMemoryifNeeded()函数检测内存是否充足。如果内存不满足,redis会删除当前指令清理存储空间。清理数据的策略称为逐出算法。
影响数据逐出的相关配置:
最大可使用内存 maxmemory
占用物理内存的比例,默认值为0,表示不限制,生产环境根据需求设定。通常设置在50%以上。
每次选取待删除数据的个数maxmeory-samples
选取数据时并不会全库扫描,导致严重性能消耗,降低读写性能,因此随机获取数据的方式作为待检测删除数据。
删除策略
maxmemory-policy
达到最大内存后的,对被挑选出来的数据进行删除的策略。

影响数据逐出的相关配置:
检测易失数据(可能会过期的数据集server.db[i].expires)
volatile-lru:最近最少使用的数据淘汰
volatile-lfu:最近使用次数最少的数据淘汰
volatile-ttl:选择要过期的数据淘汰
volatile-random:任意选择数据淘汰
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Redis是一款高性能的Key-Value存储系统,它提供了多种数据结构和丰富的功能,能够满足各种存储需求。在Redis中,内存淘汰是一种非常重要的机制,通过控制内存使用来保证系统的稳定性和性能。 内存淘汰是Redis中的一个重要机制,它可以将一部分数据内存中删除,以释放更多的内存空间。在Redis中,内存淘汰一般有几种策略,包括LRU(Least Recently Used)、LFU(Least Frequently Used)、Random等等,而Redis默认的内存淘汰策略是LRU。 但是,在一些场景中,Redis中的数据并不是按照时间顺序进行访问的,而是需要在指定的时间点过期。为了解决这个问题Redis还提供了一种特殊的内存淘汰策略——volatile-lru和volatile-ttl。这两种内存淘汰策略的特点是:它们只会淘汰过期数据或者TTL(Time To Live)值到期的数据,而不会淘汰未过期数据。 在使用这两种策略时,需要加上volatile选项,例如指定maxmemory-policy为volatile-lru或volatile-ttl。此时,Redis会将未过期数据和已经过期但未被删除的数据分别保存在两个不同的哈希表中,内存淘汰只会针对已过期但仍在内存中的数据进行操作。 因此,Redis可以通过特殊的内存淘汰策略来解决不会过期数据问题。通过使用可volatile-lru和volatile-ttl两种策略,Redis只会淘汰过期数据,而不会淘汰未过期数据,从而保证系统的正确性和稳定性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值