Redis的五大数据类型实现原理

1. 对象的类型与编码

  Redis使用前面说的五大数据类型来表示键和值,每次在Redis数据库中创建一个键值对时,至少会创建两个对象,一个是键对象,一个是值对象,而Redis中的每个对象都是由 redisObject 结构来表示:

typedef struct redisObject{ //类型 unsigned type:4; //编码 unsigned encoding:4; //指向底层数据结构的指针 void *ptr; //引用计数 int refcount; //记录最后一次被程序访问的时间 unsigned lru:22; }robj ① type属性

  对象的type属性记录了对象的类型,这个类型就是前面讲的五大数据类型:

图片名称

  可以通过如下命令来判断对象类型:

type key

图片名称

  注意:在Redis中,键总是一个字符串对象,而值可以是字符串、列表、集合等对象,所以我们通常说的键为字符串键,表示的是这个键对应的值为字符串对象,我们说一个键为集合键时,表示的是这个键对应的值为集合对象。

② encoding 属性和 *prt 指针

  对象的 prt 指针指向对象底层的数据结构,而数据结构由 encoding 属性来决定。

图片名称

  而每种类型的对象都至少使用了两种不同的编码:

图片名称

  可以通过如下命令查看值对象的编码:

OBJECT ENCODING key

  比如 string 类型:

图片名称

2. 字符串对象

  字符串是Redis最基本的数据类型,不仅所有key都是字符串类型,其它几种数据类型构成的元素也是字符串。注意字符串的长度不能超过512M。

  ① 编码

  字符串对象的编码可以是int,raw或者embstr。

  1、int 编码:保存的是可以用 long 类型表示的整数值。

  2、raw 编码:保存长度大于44字节的字符串。

  3、embstr 编码:保存长度小于44字节的字符串。

图片名称

  由上可以看出,int 编码是用来保存整数值,raw编码是用来保存长字符串,而embstr是用来保存短字符串。其实 embstr 编码是专门用来保存短字符串的一种优化编码,raw 和 embstr 的区别:

图片名称

图片名称

  embstr与raw都使用redisObject和sds保存数据,区别在于,embstr的使用只分配一次内存空间(因此redisObject和sds是连续的),而raw需要分配两次内存空间(分别为redisObject和sds分配空间)。因此与raw相比,embstr的好处在于创建时少分配一次空间,删除时少释放一次空间,以及对象的所有数据连在一起,寻找方便。而embstr的坏处也很明显,如果字符串的长度增加需要重新分配内存时,整个redisObject和sds都需要重新分配空间,因此redis中的embstr实现为只读。

  ps:Redis中对于浮点数类型也是作为字符串保存的,在需要的时候再将其转换成浮点数类型。

  ② 编码的转换

  当 int 编码保存的值不再是整数,或大小超过了long的范围时,自动转化为raw。

  对于 embstr 编码,由于 Redis 没有对其编写任何的修改程序(embstr 是只读的),在对embstr对象进行修改时,都会先转化为raw再进行修改,因此,只要是修改embstr对象,修改后的对象一定是raw的,无论是否达到了44个字节。

3. 列表对象

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zwzzff.html