Redis——Redis中的对象与编码需要合理的结合

对象的类型和编码

Redis使用对象来表示数据库中的键和值,每当我们创建一个键值对,至少创建两个对象

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

类型

键总是一个字符串对象

 

 

编码和底层实现

encoding属性记录了对象所使用的编码,也就是这个对象使用了什么数据结构作为对象的底层实现

 

 

 

字符串对象

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

如果字符串对象保存的是整数值,并且这个整数值可以用long类型来表示,那么字符串对象会将整数值保存在字符串对象结构的ptr属性里,并将字符串对象的编码设置为int

如果保存的是字符串值,并且这个字符串值的长度大于32字节,字符串对象将使用一个简单动态字符串(SDS)保存这个字符串值,并且编码设置为raw 

如果保存的是一个小等于32字节的字符串值,那么字符串对象将使用embstr编码的方式来保存这个字符串值

 

 

raw编码会调用两次内存分配函数来分别创建redisObject结构和sdshdr结构

embstr编码则通过一次内存分配函数来分配一块连续的空间

使用embstr编码的字符串对象保存短字符串值的好处

 long double类型的浮点数在Redis中也是作为字符串值来保存的

 

编码的转换

int和embstr编码的字符串,条件满足,转换为raw编码

embstr编码的字符串实际上是只读的,修改就会变成raw编码

 

 字符串命令的实现

 

列表对象

编码可以是ziplist或者linkedlist

ziplist编码的列表使用压缩列表作为底层实现,每个压缩列表节点保存了一个列表元素

linkedlist编码的列表对象使用双端链表作为底层实现,每个双端链表节点都保存了一个字符串对象,而每个字符串对象都保存了一个列表元素

双端链表结构中包含了多个字符串对象,字符串对象是Redis五种类型对象中唯一一种会被其它四种类型对象嵌套的对象

编码转换

 上限值可以修改

 对于使用ziplist编码的列表对象,任何一个条件不被满足时,就会执行转换操作

列表命令的实现

哈希对象

哈希对象可以是ziplist或者hashtable

 

 

 

hashtable编码的哈希对象使用字典作为底层实现 

 

 编码转换

任意一个不被满足就会转换编码格式

哈希命令的实现

集合对象

编码可以是intset或者hashtable

intset编码的集合对象使用整数集合作为底层实现

 

 hashtable编码的集合对象使用字典作为底层实现

字典的每个键都是一个字符串对象,每个字符串对象包含了一个集合元素,而字典的值全部被设置为NULL

编码的转换

集合命令的实现

 

有序集合对象

编码使用ziplist或者skiplist

ziplist使用压缩列表作为底层实现,每个集合元素使用两个挨在一起的压缩列表节点来保存,第一个节点保存元素的成员,第二个元素则保存元素的分值

压缩列表内的集合元素按分值从小到大进行排序

 

 

 

skiplist编码的有序集合对象使用zset结构作为底层实现

一个zset结构同时包含一个字典和一个跳跃表

 

 

 

zsl跳跃表按分值从小到大保存了所有集合元素,每个跳跃表节点都保存了一个集合元素:

Object属性保存了元素的成员,score属性保存了元素的分值,通过跳跃表可以进行范围型操作

dict字典为有序集合创建了一个从成员到分值的映射,字典中的每个键值对都保存了一个集合元素,键是元素的成员,值是元素的分值。

通过这个字典,O(1)的复杂度查找给定成员的分值

有序集合每个元素的成员都是一个字符串对象,每个元素的分值都是一个double类型的浮点数

跳跃表和字典通过指针来共享相同元素的成员和分值,所以不会产生任何重复成员或者分值,也不会因此而浪费额外的内存

 

编码的转换

 

有序集合命令的实现

类型检查与命令多态

Redis中用于操作键的命令基本上可以分为两种类型

一种是可以对任何类型的键执行,比如DEL命令、EXPIRE命令、RENAME命令、TYPE命令、OBJECT命令

另一种命令只能对特定类型的键执行

类型检查的实现

类型特定命令所进行的类型检查是通过redisObject结构的type属性来实现的

多态命令的实现

除了根据值对象的类型判断是否执行命令,还会根据值对象的编码方式,选择正确的命令

比如LLEN命令是多态的,如果对象的编码是ziplist,就要用ziplistLen函数返回长度

如果对象的编码是linkedlist,就要用listLength函数来返回双端链表的长度

实际上,我们可以将DEL、EXPIRE、TYPE等命令也成为多态命令

内存回收

Redis构建了引用计数技术实现的内存回收机制

对象共享

对象的引用计数属性还带有对象共享的作用

Redis会共享值为0到9999的字符串对象

共享对象不单单只有字符串键可以使用,那些在数据结构中嵌套了字符串对象的对象也可以使用

对象的空转时长

最后一个属性lru,记录了对象最后一次被命令程序访问的时间:

OBJECT IDLETIME命令可以打印出给定键的空转时长,这一空转时长就是通过将当前时间减去键的值对象的lru时间计算得出的

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值