redisobject详解

前面说到,Redis对象有5种类型;无论是哪种类型,Redis都不会直接存储,
而是通过redisObject对象进行存储。
  • redisObject对象非常重要,Redis对象的类型、内部编码、内存回收、共享对象等功能,都需要redisObject支持,下面将通过redisObject的结构来说明它是如何起作用的。
  • redisObject的定义如下(列出了与保存数据有关的三个属性):
typedef struct redisObject 
{ 
	unsigned type:4; 
	unsigned encoding:4; 
	unsigned lru:REDIS_LRU_BITS;  
	/* lru time (relative to server.lruclock) */  
	int refcount; 
	void *ptr;
} robj;

redisObject的每个字段的含义和作用如下:
(1)type
type字段表示对象的类型,占4个比特;目前包括REDIS_STRING(字符串)、REDIS_LIST (列表)、REDIS_HASH(哈希)、REDIS_SET(集合)、REDIS_ZSET(有序集合)。
当我们执行type命令时,便是通过读取RedisObject的type字段获得对象的类型;如下图所示:
在这里插入图片描述

(2)encoding

  • encoding表示对象的内部编码,占4个比特。
    对于redis支持的每种类型都至少有两种编码,对于字符串有int、embsre、row三种
    通过encoding属性,redis可以根据不同的使用场景来对对象使用不同的编码,大大提高的redis的灵活性和效率。
    在这里插入图片描述
  • 以列表对象为例,有压缩列表和双端链表两种编码方式;如果列表中的元素较少,
    Redis倾向于使用压缩列表进行存储,因为压缩列表占用内存更少,而且比双端链表可以更快载入;当列表对象元素较多时,压缩列表就会转化为更适合存储大量元素的双端链表。3.2版本以后都采用quicklist, 是压缩链表和双端链表的结合。
  • 什么意思呢,比如,一个包含三个结点的quicklist,如果每个结点的ziplist又包含四个数据项,那么对外表现上,这个list就总共包含12个数据项。这样的设计,实际上是对于时间和空间的一种折中
  • linkedlist便于在表的两端进行push和pop操作,但是它的内存开销较大。首先,它的每个节点除了要保存数据之外还要额外保存两个指针;其次,双向链表的各个节点是单独的内存块,地址不连续,容易产生内存碎片,还容易造成抖动。
    ziplist由于是一整块连续的内存,存储效率很高,但不利于添加和删除操作,每次都会重新realloc,尤其是当ziplist很长的时候,一次realloc造成的开销特别的大,查询的开销也特别的大。

在这里插入图片描述

列表、hash、集合、有序结合的内部编码实例图:
在这里插入图片描述

这里来一个redisObject的全类型图:

在这里插入图片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章