Redis五种数据类型的底层实现总结

  • 时间:
  • 浏览:0
  • 来源:跟我学网络

最后发布:2019-10-02 22:34:13首次发布:2019-10-02 20:59:07

Redis的五种数据类型:

  • 字符串(string)
  • 列表(list)
  • 哈希(hash)
  • 集合(set)
  • 有序集合(zset)

Redis所用到的底层数据结构:

  • long类型的整数
  • 简单动态字符串(sds)
  • emb编码的简单动态字符串(embstr)
  • 链表(实际是双端链表 linkedlist)
  • 字典(实际是哈希表 hashtable)
  • 整数集合(intset)
  • 压缩列表(ziplist)
  • 跳跃表(skiplist)

对象系统

redis并没有直接使用以上的数据结构来实现键值对数据库,而是基础这些数据结构创建了一个对象系统,包含:字符串对象、列表对象、哈希对象、集合对象和有序集合对象,这些对象都至少用到了一种数据结构。

使用对象的优点:

  • 针对不同的使用场景,为对象设置不同的数据结构实现,从而优化对象在不同场景下的使用效率
  • Redis的对象系统实现了基于引用计数技术的内存回收机制,当程序不再使用某个对象的时候,这个对象所占用的内存就会自动释放
  • Redis还基引用计数技术实现了对象共享机制,在适当的条件下,通过让多个数据库键共享同一个对象来节约内存
  • Redis的对象带有访问时间的记录信息,该信息可以用于计算数据库键的空转时长,在服务器启用了maxmemory功能的情况下,空转时长较大的那些键可能会优先被服务器删除

对象的类型和编码

一个键值对会至少创建两个对象:键对象、值对象

如set a “a”命令,会创建两个字符串对象,redis中的每个对象由一个redisObject结构表示:

typedef struct redisObject{
	unsigned type:4; 
	unsigned encoding 4; 
	void * ptr; 
	......
}robj;

对象类型:



所有的键的对象类型都是字符串对象,使用type命令可以查看一个键值对的值对象类型:

编码和底层实现: 对象的ptr指针指向对象的底层数据结构,这些数据结构由encoding(编码)属性决定,下图为对象的编码表:





每种类型的对象都至少使用的两种不同的编码,可以通过如下命令查看对象所使用的编码:



下图列出了每种对象可以使用的编码:



下图为不同的编码的对象所对应的object encoding 命令输出值:





同一种数据类型的redis可以有多种底层实现数据结构,极大地提升了reids的灵活性和效率,下面列出不同的对象类型,以及相同的对象类型不同的值的情况下所对应的底层数据结构。

字符串对象

字符串对象可以使用的编码有:int、raw、embstr

embstr编码是专门用于保存短字符串的一种编码方式。

列表对象

列表对象的编码可以是ziplist或者linkedlist

哈希对象

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

集合对象

集合对象的编码可以是intset或者hashtable

有序集合对象

有序集合对象的编码可以是ziplist或者skiplist