redis对象

对象的类型与编码

redis使用对象来表示数据库中的键和值,每次当我们在redis的数据库中新创建一个键值对时,我们至少会创建两个对象,一个对象用作键值对的键(键对象),另一个对象用作键值对的值(值对象)。

redis中美国对象都由redisObject结构表示:

typedef struct redisObject{
    //类型
    unsigned type:4;
    //编码
    unsigned encoding:4;
    //指向底层实现数据结构的指针
    void *ptr;
}

类型(type):
对象的type属性记录了对象的类型,这个属性可以是以下表中其中一个。

类型常量 对象的名称
REDIS_STRING 字符串对象
REDIS_LIST 列表对象
REDIS_HASH 哈希对象
REDIS_SET 集合对象
REDIS_ZSET 有序集合对象

编码(encoding):
相同的类型(type)会对应不同的编码,且不同编码其含义也不一样,之后会一一介绍。

字符串对象

字符串对象的编码(encoding)可以是int、raw或embstr。
如果一个字符串对象保存的是整数值,并且这个整数值可以用long类型来表示,那么次字符串的编码(encoding)为int
如果字符串对象保存的是一个字符串值,并且这个字符串值的长度大于39字节,那么字符串对象使用简单动态字符串(SDS)来保存,并将编码(encoding)设置为raw。
如果字符串对象保存的是一个字符串值,并且这个字符串值的长度小于等于39字节,那么编码(encoding)为embstr。

编码转换:
int编码的字符串对象和embstr编码的字符串对象在条件满足的情况下,会被转换为raw编码的字符串对象。
比如:int类型转换为长度大于39字节,并且不是long类型的字符串。

列表对象

列表对象可以是ziplist或者linkedlist
ziplist编码的列表对象使用压缩列表作为底层实现,每个压缩列表节点(entry)保存了一个列表元素。
linkedlist编码的列表对象使用双端链表作为底层实现。

编码转换:
当列表对象可以同时满足以下两个条件时,列表对象使用ziplist编码:
列表对象保存的所有字符串元素的长度都小于64字节。
列表对象保存的元素数量小于512个;
若不能满足则使用linkedlist。

哈希对象

哈希对象可以是ziplist或者hashtable

ziplist编码的列表对象使用压缩列表作为底层实现,每两个压缩列表节点(entry)保存了一个为键一个为值的字符串对象。
hashtable编码使用字典作为底层实现,哈希对象中的每个键值对都使用一个字典键值对来保存。

编码转换:
当列表对象可以同时满足以下两个条件时,列表对象使用ziplist编码:
列表对象保存的所有字符串元素的长度都小于64字节。
列表对象保存的元素数量小于512个;
若不能满足则使用hashtable。

集合对象

集合对象的编码可以是intset或者hashtable
intset编码的集合对象使用整数集合作为底层实现。
hashtable编码使用字典作为底层实现,哈希对象中的每个键值对都使用一个字典键值对来保存。

编码转换:
当列表对象可以同时满足以下两个条件时,列表对象使用intset编码:
列表对象保存的所有元素都是整数。
列表对象保存的元素数量小于512个;
若不能满足则使用hashtable。

有序集合对象

有序集合对象的编码可以是ziplist或者skiplist
ziplist编码的有序集合对象使用压缩列表作为底层实现,每个集合元素使用两个紧挨在一起的压缩列表节点来保存,第一个节点保存元素的成员(member),第二个元素则保存元素的分值(score)。
skiplist采用跳跃列表作为底层实现。

编码转换:
当列表对象可以同时满足以下两个条件时,列表对象使用ziplist编码:
列表对象保存的所有字符串元素的长度都小于64字节。
列表对象保存的元素数量小于128个;
若不能满足则使用skiplist。

内存回

收采用引用计数法进行回收没有用到的对象。

对象共享

若为1-9999的字符串,则会共享一个内存地址。

对象空转时间

redisObject含有一个LRU属性,该属性记录了对象最后一次被命令程序访问的时间,由此可计算对象空转时间。

总结

redis数据库中的每个键值对的键和值都是一个对象。
redis共有字符串、列表、哈希、集合、有序集合五种类型的对象,每种类型的对象至少都有两种以上的编码方式,不同的编码可以在不同的使用场景上优化对象的使用效率。
服务器在执行某些命令之前,会先检查给定键的类型能否执行指定的命令,而检查一个键的类型就是检查键的值对象的类型。
redis的对象系统带有引用计数实现的内存回收机制。
redis会共享值为0到9999的字符串对象。
对象会记录自己的最后一次被访问时间,这个时间可以用于计算对象的空转时间。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Redis是基于上一篇文章所说的数据结构创建了一个对象系统,这个系统包含字符串对象、列表对象、哈希对象、集合对象和...
    JingQ阅读 3,297评论 0 0
  • 上周看完Redis设计与实现,过程结合Redis的unstable分支的源码来对照,基本对Redis的实现原理有了...
    zcliu阅读 4,615评论 0 1
  • Redis的内存优化 声明:本文内容来自《Redis开发与运维》一书第八章,如转载请声明。 Redis所有的数据都...
    meng_philip123阅读 18,982评论 2 29
  • 参考来源 Redis的内存优化 Redis所有的数据都在内存中,而内存又是非常宝贵的资源。对于如何优化内存使用一直...
    秦汉邮侠阅读 5,051评论 0 2
  • 关于一场忽大忽小的雨
    年纪轻轻的撸妈阅读 1,248评论 0 0