Skip to content

Latest commit

 

History

History
124 lines (93 loc) · 4.44 KB

redis_6_对象.md

File metadata and controls

124 lines (93 loc) · 4.44 KB

redis 中的对象

在 redis 中,并没有直接使用前面所介绍的那些数据结构(动态字符串,压缩列表,字典)来实现键值对数据库,而是基于这些数据结构创建了一个对象系统,也就是说,用对象来封装了这些底层的数据结构。

五种对象:字符串对象、列表对象、哈希对象、集合对象和有序集合对象,每种对象至少用到了一种前面介绍过的数据机构。

使用对象的好处是:

  • redis 在执行命令之前,根据对象的类型来判断它是否可以执行给定的命令。
  • 针对不同的使用场景,为对象设置多种不同的数据结构实现,从而优化对象在不同场景下的使用效率。即,redis可以根据不同的场景来为一个对象设置不同的编码(使用不同的数据结构来存储数据)。例如,元素较少时,使用压缩列表作为列表对象的底层实现;元素变多时,转换成适合大量元素的双端列表
  • 实现了基于引用计数的内存回收机制和对象共享机制。

redis 中每个对象都由一个 redisObject 结构表示:

typedef struct redisObject {
	// 类型,五种对象之一
	unsigned type: 4;

	// 编码,底层实现
	unsigned encoding:4;

	// 指向底层实现数据结构的指针
	void* ptr;
} robj;

字符串对象

字符串对象的编码可以是 int、raw 或者 embstr。 embstr 编码是专门用于保存短字符串的一种优化编码方式,这种编码和 raw 编码(对应底层为sds,简单动态字符串)一样,也是使用 sdshdr 结构表示字符对象。不同的是,raw 编码会调用2次内存分配来创建 redisObject 和 sdshdr 结构,而 embstr 编码只调用一次,分配一块连续的空间。 2中编码方式内存结构如下:

pic

pic

列表对象

列表对象的编码可以是 ziplist 或者 linkedlist。 图示如下:

pic

pic

从上图中可以看出,linkedlist 中嵌套了字符串对象字符串对象redis五种类型中唯一一种会被其他四种类型对象嵌套的对象。

编码转换

** 何时使用 ziplist 编码**:

  • 字符串的长度小于64字节
  • 列表中元素个数小于512个

上述的阈值是默认的,可以修改

哈希对象

哈希对象的编码可以是ziplist 或者 hashtable

使用 ziplist 编码的哈希对象

ziplist 编码的哈希对象
+-----------------------+
|    redisObject 	 	|
+-----------------------+
|	      type 			|
|	   REDIS_HASH		|
+-----------------------+
|	    encoding        |
|REIDS_ENCODING_ZIPLIST	|
+-----------------------+	 +----------+
|    	  ptr			|--> |  压缩列表 	|
+-----------------------+	 +----------+
|         ...           |
+-----------------------+

压缩列表的底层实现示意图:

+-------+-------+-------+-------+------+-------+---+-------+
|zlbytes|zltail | zllen | "name"| "Tom"| "age" | 25| zlend |
+-------+-------+-------+-------+------+-------+---+-------+
							|       |      |	 |
							+-------+      +-----+
								|			  \	
						第一个添加的键值对	     最后添加的键值对

使用 hashtable 编码的哈希对象

示意图如下: ziplist 编码的哈希对象

+-----------------------+
|    redisObject 	 	|
+-----------------------+
|	      type 			|
|	   REDIS_HASH		|
+-----------------------+
|	    encoding        |
|   REIDS_ENCODING_HT	|
+-----------------------+	 +--------------+
|    	  ptr			|--> |  dict 		|
+-----------------------+	 +--------------+   +--------------+
|         ...           |	 | StringObject |-->| StringObject |
+-----------------------+	 |    "age"     |	|      25      |
							 +--------------+   +--------------+
							 | StringObject |
							 |    "name"	|-->+--------------+
							 +--------------+   | StringObject |
							 					|     "Tom"    |
							 					+--------------+

编码转换(与列表对象类似)

何时使用 ziplist 编码:

  • 键和值 长度 < 64字节
  • 键值对数量 < 512个

上述的阈值是默认的,可以修改