[redis设计与实现][7]基本数据结构——对象

Redis对基础数据类型进行了封装,构建出上层的对象系统,这个系统包含:字符串对象、列表对象、哈希对象、集合对象和有序集合对象。

Redis对象结构:
[cce lang=”c”]
typedef struct redisObject {
//类型
unsigned type:4;
//编码
unsigned encoding:4;
//LRU时间
unsigned lru:REDIS_LRU_BITS; /* lru time (relative to server.lruclock) */
//引用计数
int refcount;
//底层实现数据结构的指针
void *ptr;
} robj;
[/cce]

相关宏定义:
[cce lang=”c”]
#define REDIS_LRU_BITS 24
#define REDIS_LRU_CLOCK_MAX ((1<<REDIS_LRU_BITS)-1) /* Max value of obj->lru */
#define REDIS_LRU_CLOCK_RESOLUTION 1 /* LRU clock resolution in seconds */
[/cce]

Redis对象类型:(使用type命令查看)
[cce lang=”c”]
/* Object types */
#define REDIS_STRING 0
#define REDIS_LIST 1
#define REDIS_SET 2
#define REDIS_ZSET 3
#define REDIS_HASH 4

//对象编码类型:(使用object encoding命令)
#define REDIS_ENCODING_RAW 0 /* Raw representation */
#define REDIS_ENCODING_INT 1 /* Encoded as integer */
#define REDIS_ENCODING_HT 2 /* Encoded as hash table */
#define REDIS_ENCODING_ZIPMAP 3 /* Encoded as zipmap */
#define REDIS_ENCODING_LINKEDLIST 4 /* Encoded as regular linked list */
#define REDIS_ENCODING_ZIPLIST 5 /* Encoded as ziplist */
#define REDIS_ENCODING_INTSET 6 /* Encoded as intset */
#define REDIS_ENCODING_SKIPLIST 7 /* Encoded as skiplist */
[/cce]

不同类型和编码的对象:

类型 编码 对象
REDIS_STRING REDIS_ENCODING_INT 使用整数值实现的字符串对象
REDIS_STRING REDIS_ENCODING_EMBSTR 这货redis3.0引入的,不管
REDIS_STRING REDIS_ENCODING_RAW sds实现的字符串对象
REDIS_LIST REDIS_ENCODING_ZIPLIST 使用压缩列表实现的列表对象
REDIS_LIST REDIS_ENCODING_LINKEDLIST 使用双向链表实现的列表对象
REDIS_HASH REDIS_ENCODING_ZIPLIST 使用压缩列表实现的哈希对象
REDIS_HASH REDIS_ENCODING_HT 使用字典实现的哈希对象
REDIS_SET REDIS_ENCODING_INTSET 使用整数集合实现的集合对象
REDIS_SET REDIS_ENCODING_HT 使用字典实现的集合对象
REDIS_ZSET REDIS_ENCODING_ZIPLIST 使用压缩列表实现的有序集合对象
REDIS_ZSET REDIS_ENCODING_SKIPLIST 使用跳跃表想和字典实现的有序集合对象


字符串对象:
整数(long)被保存为int类型
浮点保存为字符串,浮点运算(INCRYBYFLOAT)redis先转成浮点,进行运算后再转回字符串

列表对象:
列表对象同时满足一下两个条件时,列表对象使用ziplist编码
列表对象保存的所有字符串元素的长度都小于64个字节(list-max-ziplist-value)
列表对象保存的元素数量小于512个(list-max-ziplist-entries)
不能满足条件的都需要使用linkedlist编码。

哈希对象:
使用压缩列表,键和值分别作为节点按顺序放入列表
使用ziplist的条件:
哈希对象保存的所有键值对的键和值的字符串长度小于64个字节(hash-max-ziplist-value)
哈希对象保存的键值对数量小于512个(hash-max-ziplist-entries)

集合对象:
hashtable编码,字典的每个键都是一个字符串对象,字典的值全部设置为NULL
使用intset编码条件:
集合对象保存的所有元素是整数值
集合对象保存的元素数量不超过512个(set-max-intset-entries)
不满足条件的集合对象需要使用hashtable编码

有序集合对象:
ziplist编码的有序集合,每个集合元素使用两个紧挨在一起的压缩节点列表来保存,第一个节点保存元素的成员,第二个节点保存元素的分值。
skiplist编码的有序集合,采用一个skiplist和一个hashtable实现。
使用ziplist编码条件:
有序集合保存的元素数量小于128个(zset-max-ziplist-entries)
有序集合保存的所有元素成员的长度都小于64字节(zset-max-ziplist-value)

对象共享:
Redis在初始化时,会创建1w个字符串对象(REDIS_SHARED_INTEGERS),包含整数0~9999,当需要使用这些对象的时候,会使用这些对象的引用(引用计数)而不新创建。
[cce lang=”c”]
if (value >= 0 && value < REDIS_SHARED_INTEGERS) {
incrRefCount(shared.integers[value]);
o = shared.integers[value];
}
[/cce]

转载自:https://coolex.info/blog/454.html

时间: 2024-10-03 18:07:06

[redis设计与实现][7]基本数据结构——对象的相关文章

[redis设计与实现][4]基本数据结构——跳跃表

Redis使用跳跃表和字典共同来实现有序集合键(sorted set). 定义: 跳跃表节点: [cce lang="c"] typedef struct zskiplistNode { //成员对象 robj *obj; //分值 double score; //后退指针 struct zskiplistNode *backward; //层结构 struct zskiplistLevel { //前进指针 struct zskiplistNode *forward; //跨度 un

[redis设计与实现][3]基本数据结构——字典

Redis字典采用哈希表实现. 哈希表: [cce lang="c"] typedef struct dictht { //哈希表数组 dictEntry **table; //哈希表大小 unsigned long size; //哈希表掩码,用于计算索引值,总是等于size – 1 unsigned long size mask; //已有的节点数量 unsigned long used; } dictht; [/cce] 哈希表节点: [cce lang="c"

[redis设计与实现][1]基本数据结构——sds

SDS(Simple Dynamic String):对C字符串的封装,可修改.可自动伸缩的字符串实现.Redis默认的字符串实现. SDS定义:(sds.h) [cce lang="c"] struct sdshdr { unsigned int len; unsigned int free; char buf[]; }; [/cce] 与C字符串的区别: * 常数复杂度获取字符串长度(字符串长度已经记录在结构体中) * 杜绝缓冲区溢出(每次操作前都会检查空间是否充足,自动扩张和收缩

[redis设计与实现][6]基本数据结构——压缩列表

压缩列表(ziplist)是列表键和哈希键的底层实现之一. 压缩列表结构: 属性 类型 长度 用途 zlbytes uint32_t 4字节 记录整个压缩列表占用的内存字节数:在对压缩列表进行内存重分配,或者计算zlend的位置时使用 zltail uint32_t 4字节 记录压缩列表尾节点记录压缩列表的起始地址便宜:用于快速定位尾节点 zllen uint16_t 2字节  记录压缩列表包含的节点数量:当这个值小于UINT64_MAX(65535)时,这个属性的值就是压缩列表包含的节点数量:

[redis设计与实现][5]基本数据结构——整数集合

整数集合(intset)用于集合键.当一个集合只包含整数值元素,并且数量不多的时候,会使用整数集合作为集合键的底层实现.相对于直接保存字符串,整数集合能够很好地节约内存,但是由于是数组保存,需要特别关注数组长度. 定义:(intset.h) [cce lang="c"] typedef struct intset { //编码方式 uint32_t encoding; //集合包含的元素数量 uint32_t length; //保存元素的数组 int8_t contents[]; }

设计模式怎样解决设计问题[1] 寻找合适的对象

设计模式怎样解决设计问题[1] 寻找合适的对象  面向对象设计最困难的部分是将系统分解成对象集合.因为要考虑许多因素:封装.依赖关系.灵活性.性能.演化.复用等等,它们都影响着系统的分解,并且这些因素通常都是互相冲突的. 寻找合适的类是为了便于你设计出好用的类,包含了3种设计模式: Composite模式(组合模式),State模式(状态模式)以及Strategy模式(策略模式)   Composite模式(组合模式) http://www.cnblogs.com/jiese/p/3168844

《Redis设计与实现》阅读:Redis底层研究之简单动态字符串SDS

        除仅用于字符串字面量的情况外,对于可以被修改值的字符串的表示,Redis底层并没有采用C语言传统的字符串表示,即以空字符结尾的字符数组,而是采用专门为其设计的简单动态字符串作为其默认字符串表示,其英文全称为Simple Dynamic String,简称SDS.除了用于保存数据库中字符串值外,SDS也可以用于缓冲区buffer,比如AOF中的缓冲区.客户端输入缓冲区等.本文,我们将详细研究简单动态字符串SDS的实现及其在性能等方面的独特之处.             注:内容总结

[redis设计与实现][10]sentinel——简介和启动

Sentinel(Redis 3.0.0-rc1) Sentinel是Redis HA方案,一个或多个Sentinel实例组成的Sentinel系统,可以监视任意多个主服务器(master), 以及这些主服务器属下的所有从服务器(slave),并在被监视的主服务器进入下线状态时,自动在将被下线主服务器属下的某个从服务器升级为新的主服务器, 然后由新的主服务器代替已下线的主服务器继续处理命令请求. 基础数据结构 typedef struct sentinelRedisInstance { // 当

Web设计中如何使用XML数据源对象

web|xml|对象|设计|数据|数据源 XML数据源对象是一个ActiveX控件,允许你在XML文件和HTML页面之间操作数据.本文将向你展示如何从各种XML数据源中提取数据,以及如何使用JavaScript显示这些数据. XML数据源对象DSO是一个微软ActiveX控件,构建在微软IE4以后的版本上.这个对象允许你把一个外部的XML文件或者嵌入HTML文件中的内容提取到HTML页面中. 你可以在一个Web页面中使用XML - DSO从一个外部XML文件中选取内容,从嵌入Web页面的XML中