redis 过期策略和对象引用

(1) LRU

  • lru记录的是对象最后一次被命令程序访问的时间,占据的比特数不同的版本有所不同(如4.0版本占24比特,2.6版本占22比特)。
  • 通过对比lru时间与当前时间,可以计算某个对象的闲置时间;object idletime命令可以显示该闲置时间(单位是秒)。object idletime命令的一个特殊之处在于它不改变对象的lru值。

在这里插入图片描述

	lru值除了通过object idletime命令打印之外,还与Redis的内存回收有关系:如果Redis打开了
maxmemory选项,且内存回收算法选择的是volatile-lru或allkeys—lru,那么当Redis内存占用
超过maxmemory指定的值时,Redis会优先选择空转时间最长的对象进行释放。

(2) refcount

refcount与共享对象

  • refcount记录的是该对象被引用的次数,类型为整型。refcount的作用,主要在于对象的引用计数和内存回收。当创建新对象时,refcount初始化为1;当有新程序使用该对象时,refcount加1;当对象不再被一个新程序使用时,refcount减1;当refcount变为0时,对象占用的内存会被释放。

  • Redis中被多次使用的对象(refcount>1),称为共享对象。Redis为了节省内存,当有一些对象重复出现时,新的程序不会创建新的对象,而是仍然使用原来的对象。这个被重复使用的对象,就是共享对象加粗样式。目前共享对象仅支持整数值的字符串对象

    共享对象的具体实现:

  • Redis的共享对象目前只支持整数值的字符串对象。之所以如此,实际上是对内存和CPU(时间)的平衡:共享对象虽然会降低内存消耗,但是判断两个对象是否相等却需要消耗额外的时间。对于整数值,判断操作复杂度为O(1);对于普通字符串,判断复杂度为O(n);而对于哈希、列表、集合和有序集合,判断的复杂度为O(n^2)。

  • 虽然共享对象只能是整数值的字符串对象,但是5种类型都可能使用共享对象(如哈希、列表等的元素可以使用)。

  • 就目前的实现来说,Redis服务器在初始化时,会创建10000个字符串对象,值分别是0~9999的整数值;当Redis需要使用值为0 ~ 9999的字符串对象时,可以直接使用这些共享对象。10000这个数字可以通过调整参数REDIS_SHARED_INTEGERS(4.0中是OBJ_SHARED_INTEGERS)的值进行改变。

  • 共享对象的引用次数可以通过object refcount命令查看,如下图所示。命令执行的结果页佐证了只有0~9999之间的整数会作为共享对象。
    在这里插入图片描述

(3) 总结:

  • 综上所述,redisObject的结构与对象类型、编码、内存回收、共享对象都有关系;一个redisObject对象的大小为16字节:

     4bit+4bit+24bit+4Byte+8Byte=16Byte。
    
  • type : 4bit

  • encoding : 4bit

  • lru : 24bit

  • refcount : 4byte

  • ptr : 8byte

发布了106 篇原创文章 · 获赞 61 · 访问量 29万+

猜你喜欢

转载自blog.csdn.net/b1303110335/article/details/105327116