最高两位取值 | 表示是数据类型 | encoding字节数 | 余下的bit数 | 最大范围 |
---|---|---|---|---|
00 | 字符数组 | 一个字节 | 6bit | 63位 |
01 | 字符数组 | 两个字节 | 14bit | 2^14-1 |
10 | 字符数组 | 五个字节 | 4*8,第一个字节余下的6bit留空 | 2^32-1位 |
11 | 整数 | 1个字节 | 000000 | int16_t类型整数 |
11 | 整数 | 1个字节 | 010000 | int32_t类型整数 |
11 | 整数 | 1个字节 | 100000 | int64_t类型整数 |
11 | 整数 | 1个字节 | 110000 | 24位有符号整数 |
11 | 整数 | 1个字节 | 111110 | 8位有符号整数 |
11 | 整数 | 1个字节 | xxxxxx | 没有content,xxxx本身就表示了0-12的整数 |
//server.h
typedef struct redisObject {
unsigned type:4; //类型
unsigned encoding:4; // 编码
// 对象最后一个被命令程序访问的时间
unsigned lru:LRU_BITS; /* LRU time (relative to global lru_clock) or
* LFU data (least significant 8 bits frequency
* and most significant 16 bits access time). */
int refcount; // 引用计数
void *ptr; // 指向底层的数据结构指针
} robj;
对象 | 对象type属性 | type命令的输出 |
---|---|---|
字符串对象 | REDIS_STRING | string |
列表对象 | REDIS_LIST | list |
哈希对象 | REDIS_HASH | hash |
集合对象 | REDIS_SET | set |
有序集合对象 | REDIS_ZSET | zset |
编码常量 | 对应的数据结构 | OBJECT ENCODING命令输出 |
---|---|---|
REDIS_ENCODING_INT | long类型的整数 | “int” |
REDIS_ENCODING_EMBSTR | embstr编码的简单动态字符串 | “embstr” |
REDIS_ENCODING_RAW | 简单动态字符串 | “raw” |
REDIS_ENCODING_HT | 字典 | “hashtable” |
REDIS_ENCODING_LINKEDLIST | 双端链表 | “linkedlist” |
REDIS_ENCODING_ZIPLIST | 压缩列表 | “ziplist” |
REDIS_ENCODING_INTSET | 整数集合 | “intset” |
REDIS_ENCODING_SKIPLIST | 跳跃表和字典 | “skiplist” |
- raw
- embstr
字符串对象内容 | 长度 | 编码类型 |
---|---|---|
整数值 | - | int |
字符串值 | 小于32字节 | embstr |
字符串值 | 大于32字节 | raw |
embstr编码是专门用于保存短字符串的一种优化编码方式。这种编码和raw编码一样,都使用redisObject结构和sdshdr结构来表示对象。区别在于:
int编码和embstr编码的对象满足条件时会自动转换为raw编码的字符串对象
redis中所有键都是字符串对象,所以所有对于键的命令都是针对字符串键来构建的
- linkedlist
使用ziplist编码的两个条件如下,不满足的都用linkedlist编码(这两个条件可以在配置文件中修改):
哈希对象的编码可以是
集合对象的编码可以是:
集合使用intset需要满足两个条件,不满足时使用hashtable(参数可通过配置文件修改)
有序集合的编码可以是
// 两种数据结构通过指针共享元素成员和分值,不会浪费内存
typedef struct zset {
zskplist *zsl; //跳跃表,方便zrank,zrange
dict *dict; //字典,方便zscore
}zset;
当满足以下两个条件时,使用ziplist编码,否则使用skiplist(可通过配置文件修改)
redis的命令可以分为两大类:
redis通过对象的refcount属性记录对象引用计数信息,适当的时候自动释放对象进行内存回收
# 设置字符串
set msg "hello world"
rpush numbers 1 2 3 4 5
llen numbers
lrange numbers 0 5
# 获取键值使用的底层数据结构
object encoding numbers
# 查看对象的引用计数值
object refcount numbers
# 对象空转时长: value=now-object.lru
object idletime numbers