8.1 对象的类型与编码
Redis中的每个对象都由一个redisObject结构表示:type、encoding、ptr
typedef struct redisObject{ unsigned type:4; unsigned encoding:4; void *ptr; }
REDIS_STRING 字符串
REDIS_LIST 列表
REDIS_HASH 哈希
REDIS_SET 集合
REDIS_ZSET 有序集合
8.1.2 编码和底层实现
对象的ptr指针指向对象的底层实现数据结构,由encoding决定
编码所对应的底层数据结构
REDIS_ENCODING_INT long类型的整数
REDIS_ENCODING_EMBSTR embstr编码的简单动态字符串
REDIS_ENCODING_RAW 简单动态字符串
REDIS_ENCODING_HT 字典
REDIS_ENCODING_LINKEDLIST 双端链表
REDIS_ENCODING_ZIPLIST 压缩列表
REDIS_ENCODING_INTSET 整数集合
REDIS_ENCODING_SKIPLIST 跳跃表和字典
8.2 字符串对象
编码可以是int、embstr或raw
长度大于32字节 raw
长度小于32字节 embstr
raw会调用俩次内存分配函数来创建redisObject结构和sdshdr结构,
embstr编码则通过调用一次内存分配函数来分配一块连续的空间。
8.3 列表对象
列表对象的编码可以是ziplist或者linkedlist
同时满足以下俩个条件,列表对象使用ziplist编码:
①字符串长度都小于64字节;
②数量小于512个
不满足条件的列表对象使用linkedlist编码
8.4 哈希对象
哈希对象的编码可以是ziplist或者hashtable
ziplist编码的哈希 特点:
①保存了同一键值对的俩个节点总是紧挨在一起,保存键的节点在前,保存值的节点在后;
②新添加的节点在后面
满足以下俩个条件时,哈希对象使用ziplist::
①哈希对象保存的键和值字符串长度小于64字节
②数量小于512个
注:俩个条件值可以修改
8.5 集合对象
集合对象的编码可以使intset或者hashtable
满足以下俩个条件时,集合对象使用intset编码:
①所有元素都是整数值;
②数量不超过512。(注:数量个数可以修改)
8.6 有序集合对象
有序集合的编码可以是ziplist或者skiplist。
ziplist编码的压缩列表对象使用压缩列表作为底层实现,每个集合元素使用俩个紧挨在一起的压缩列表节点来保存,第一个节点保存元素的成员,
而第二个元素则保存元素的分值;
skiplist编码的有序集合对象使用zset结构作为底层实现,一个zset结构同时包含一个字典和跳跃表:
typedef struct zset{ zskiplist *zsl; dict *dict; }zset;当满足以下俩个条件时,对象使用ziplist编码:
①数量小于128
②成员的长度小于64字节
注:上述俩个值可以修改
8.7 类型共检查与命令多态
DEL、EXPIRE、RENAME、TYPE、OBJECT等命令可以对任何类型的键执行
SET、GET、APPEND、STRLEN等命令只能对字符串键执行;
HDEL、HSET、HGET、HLEN等命令只能对哈希键执行;
RPUSH、LPOP、LINSERT、LLEN等命令只能对列表键执行;
SADD、SPOP、SINTER、SCARD等命令只能对集合键执行;
ZADD、ZCARD、ZRANK、ZSCORE等命令只能对有序集合键执行;
8.8 内存回收
reference counting
8.9 对象共享
Redis会在初始化服务器时,创建一万哥字符串对象,0-9999.
Redis只对包含整数值的字符串对象进行共享,原因是验证操作的复杂度为O(1)
8.10 空转时长
当服务器内存回收算法为volatile-lru或allkeys-lru,那么当服务器占用的内存数超过了maxmemory选项所设置的上限值时,
空转时长较高的那部分键会优先被服务器释放。
8.11 重点回顾
Ⅰ Redis数据库中的每个键值对的键和值都是一个对象
Ⅱ Redis共有字符串、列表、哈希、集合、有序集合五种类型的对象,每种类型的对象至少都有俩种或以上的编码方式,不同的编码可以在不同的
使用场景上优化对象的使用效率。
Ⅲ 服务器在执行某些命令之前,会先检查给定键的类型能否执行制定的命令,而检查一个键的类型就是检查键的值对象的类型。
Ⅳ Redis的对象系统内存回收机制:引用计数。
Ⅴ Redis会共享值为0到9999的字符串对象
Ⅵ 对象会记录自己的最后一次被访问的时间,这个时间可以用于计算对象的空转时间。