我知道点redis-数据结构与对象(对象)-对象存储
2015-08-24 10:40
676 查看
我知道点redis-数据结构与对象(对象)-对象存储
在前面的数个章节里,我们陆续介绍了Redis用到的所有数据结构,比如SDS、双端链表、字典等。Redis并没有直接使用这些数据结构来实现键值对数据库,而是基于这些数据结构创建了一个对象系统。8.1 对象的类型和编码
redis中的每个对象都由一个redisObject结构表示,该结构中和保存数据有关的三个属性分别是type、encoding、ptr:typedef struct redisObject { // 类型 unsigned type:4; // 编码 unsigned encoding:4; // 指向底层实现数据结构的指针 void *ptr; //... } robj;
8.1.1 类型
对象的type属性记录了对象的类型,这个属性的值可以是以下列表中的一种:REDIS_STRING --> 字符串对象
REDIS_LIST --> 列表对象
REDIS_HASH --> 哈希对象
REDIS_SET --> 集合对象
REDIS_ZSET --> 有序集合对象
对于redis中保存的键值对来说,
key总是一个字符串对象,
value可以是
string、
list、
hash、
set、
zset的一种,因此:当我们称呼一个数据库键为『字符串键』时,我们指的是其对应的value是字符串对象。
TYPE命令的实现方式也与此类似,当我们对一个数据库键执行
TYPE命令时,命令返回的结果为其对应的value类型。
redis> SADD fruits apple banana cherry (integer) 3 redis> TYPE fruits set
8.1.2 编码和底层实现
对象的prt指针指向对象的底层实现数据结构,而这些数据结构由对象的
encoding属性决定。
encoding属性记录了对象所使用的编码,也就是说对象使用什么数据结构作为对象的底层实现。
使用
OBJECT ENCODING命令可以查看一个数据库键的值对象的编码:
redis> SADD numbers 1 3 5 (integer) 3 redis > OBJECT ENCODING numbers "intset"
通过
encoding属性来设定对象所使用的编码,而不是为特定类型的对象关联一种固定的编码,几大地提升了Redis的灵活性和效率,因为Redis可以根据不同的使用场景为一个对象设置不同的编码,从而优化对象在某一场景下的效率。
8.2 字符串
字符串对象的编码可以是int、
raw或者
embstr。
int
如果一个字符串对象保存的是整数值,并且这个整数值可以用
long类型来表示。那么字符串对象会将整数值保存在ptr属性中,并且
encoding = int。
raw
如果一个字符串对象保存的是一个字符串值,并且这个字符串长度
>32B,那么字符串对象将使用一个SDS来保存,并且
encoding = raw。
embstr
如果一个字符串对象保存的是一个字符串值,并且这个字符串长度
<=32B,那么字符串对象将使用一个SDS来保存,并且
encoding = embstr。
embstr编码是专门用于保存短字符串的一种优化编码方式,这种编码和
raw编码一样,都是用
redisObject和
SDS结构,但是
raw编码会调用2次内存分配分别创建
redisObject和
SDS结构,而
embstr编码会调用一次内存分配函数来分配一块连续的空间,空间中依次包含
redisObjet和
sds结构。
8.2.1 编码转换
int编码的字符串对象和embstr编码的字符串对象在条件满足的情况下,会被转换为raw编码的字符串对象。另外,因为redis没有为embstr编码的字符串对象编写任何相应的修改程序,所以embstr编码的字符串对象实际上是只读的。当我们对embstr编码的字符串对象执行任何修改命令时,程序回先将对象的编码从embstr转换为raw。因为这个原因,embstr编码的字符串对象,在执行修改命令之后,总会变成一个raw编码的字符串对象。
8.3 列表对象
列表对象的编码可以是ziplist或者
linkedlist。
ziplist
zip编码的列表对象使用压缩列表作为底层实现,每个压缩列表的节点(entry)保存了一个列表元素。
linkedlist
linkedlist编码的列表对象使用双端链表作为底层实现,每隔双端链表节点(node)都保存了一个字符串对象而每个字符串对象都保存了一个列表元素。
8.3.1 编码转换
当列表对象可以同时满足一下两个条件时,列表对象使用ziplist编码(不能满足这两个条件的列表对象使用linkedlist对象编码。):列表对象保存的所有字符串元素的长度都小于64字节;
列表对象保存的元素数量小于512个;
以上两个条件的上限是可以修改的,通过在配置文件中对
list-max-ziplist-value和
list-max-ziplist-entries进行配置即可。
8.4 哈希对象
哈希对象的编码可以是ziplist或者
hashtable。
ziplist
ziplist编码的哈希对象使用压缩列表作为底层实现,每当有新的键值对要加入到哈希对象时,程序会先将保存了键的压缩列表节点推入到压缩列表表尾,然后再将保存了值的压缩列表节点推入到压缩列表表尾,因此:
保存了同一个键值对的两个节点总是紧挨在一起,保存键的节点在前,保存值的节点在后;
先添加到哈希对象中的键值对会被放在压缩列表的表头方向,而后来添加到哈希对象的键值对会被放在压缩列表的表尾方向。
hashtable
hashtable编码的哈希对象使用字典作为底层实现,哈希对象中的每个键值对都使用一个字典键值对来保存:
字典的每隔键都是一个字符串对象,对象中保存了键值对的键;
字典的每个值都是一个字符串对象,对象中保存了键值对的值。
8.4.1 编码转换
当哈希对象同事满足一下两个条件时,哈希对象使用ziplist编码(不能满足这两个条件的哈希对象使用hashtable编码):哈希对象保存的所有键值对的键和值的字符串长度都小于64字节;
哈希对象保存的键值对数量小雨512个;
以上两个条件的上限是可以修改的,通过在配置文件中对
hash-max-ziplist-value和
hash-max-ziplist-entries进行配置即可。
8.5 集合对象
集合对象的编码可以是intset或者
hashtable.
intset
intset编码的集合对象使用整数集合作为底层实现,集合对象包含的所有对象都被保存在整数集合里面。
hashtable
hashtable编码的集合对象使用字典作为底层实现,字典的每个键都是一个字符串对象,每个字符串对象包含了一个集合元素,而字典的值全部被设置为NULL。
8.5.1 编码转换
当集合对象同时满足一下两个条件时,对象使用intset编码(不能满足这两个条件的集合对象需要使用
hashtable编码):
集合对象保存的所有元素都是整数值;
集合对象保存的元素数量不超过512个。
第二个条件的上限是可以修改的,通过修改配置项
set-max-intset-entries.
8.6 有序集合对象
有序集合的编码可以使用ziplist或者
skiplist.
ziplist
ziplist编码的有序集合对象使用压缩列表作为底层实现,每个集合元素使用两个紧挨在一起的压缩列表节点来保存,第一个节点保存元素的成员(member),而第二个元素则保存元素的分值(scope)。压缩列表内的集合元素按分值从小到大进行排列。
skiplist
skiplist编码的有序集合对象使用zset结果作为底层实现,一个zset结构同时包含一个字典和一个跳跃表:
typedef struct set { zskiplist *zsl; dict *dict; } zset;
zset结构中的zsl跳跃表按照分支从小到大保存了所有的集合元素,每个跳跃表节点都保存了一个集合元素:跳跃表节点的object属性保存了元素的成员,而跳跃表节点的score属性则保存了元素的分值。通过这个跳跃表,程序可以对有序集合进行范围型操作,比如
ZRANK、
ZRANGE等。
除此之外,zset结构中的dict字典,为有序集合创建了一个从成员到分值的映射,字典的每个键值对都保存了一个集合元素:字典的键保存了元素的成员,而字典的值保存了元素的分值。通过这个字典,程序可以用
O(1)的复杂度查找给定成员的分值,比如
ZSCORE.
8.6.1 编码转换
当有序集合对象可以同时满足一下两个条件时,对象使用ziplist编码(否则使用
skiplist编码):
有序集合保存的元素数量小于128个;
有序集合保存的所有元素成员的长度都小于64字节。
这两个条件的上限是可以修改的,配置项:
zset-max-ziplist-entries和
zset-max-ziplist-value
相关文章推荐
- 大数据学习之BigData常用算法和数据结构
- Python数据结构之:列表
- C源码@数据结构与算法->LeftistHeap
- 数据结构基础 各种遍历还原二叉树
- 数据结构学习之路-第一章:绪论
- 数据结构学习之路--序
- 数据结构之---C语言实现关键路径AOE图
- 栈和队列数据结构的基本概念及其相关的Python实现
- 数据结构与算法-线性表的实现(1)
- 数据结构与算法-如何计算时间复杂度
- 数据结构与算法-抽象数据类型
- 数据结构与算法-为什么要使用算法
- 数据机构与算法-数据结构的一些基本概念
- 数据结构与算法-函数的渐近增长
- 数据结构与算法-线性表的定义与特点
- 【数据结构导论】什么是数据结构?
- 数据结构_散列表
- 数据结构_散列表
- 黑马程序员——集合——Set集合,增强for循环,数据结构,泛型,Collections集合工具类
- Nginx基本数据结构之ngx_http_request_t结构体