//一些命令/
LPUSH 将元素推入列表头
RPUSH 将元素推入列表位
LLEN 返回列表长度
/
Redis中的每个对象由一个redisObject结构表示
typedef struct redisObject{
//类型
unsigned type:4;
//编码
unsigned encoding:4;
//指向底层实现数据结构的指针
void *ptr;
}robj;
字符串对象
字符串对象的编码可以是:int, raw,embstr
字符串长度大于39字节会用raw编码 embstr编码分配两次内存 p65
127.0.0.1:6379> SET num 10086
OK
127.0.0.1:6379> OBJECT ENCODING num
"int"
127.0.0.1:6379> SET story "long long long ago there lived a king ..."
OK
127.0.0.1:6379> STRLEN story
(integer) 41
127.0.0.1:6379> OBJECT ENCODING story
"raw"
小于39字节会用embstr编码 embstr编码分配一次内存
127.0.0.1:6379> SET story1 "long long ..."
OK
127.0.0.1:6379> STRLEN story1
(integer) 13
127.0.0.1:6379> OBJECT ENCODING story1
"embstr"
注意:long double 类型的浮点数在Redis中也是作为字符串保存的!
127.0.0.1:6379> SET pi 3.14159
OK
127.0.0.1:6379> TYPE pi
string
127.0.0.1:6379> OBJECT ENCODING pi
"embstr"
embstr字符串是只读的,当我们对embstr编码的字符串对象执行任何修改命令时,程序会将对象的编码从embstr转为raw,然后再执行修改命令
127.0.0.1:6379> GET num
"10086"
127.0.0.1:6379> OBJECT ENCODING num
"int"
127.0.0.1:6379> APPEND num "is a good number"
(integer) 21
127.0.0.1:6379> OBJECT ENCODING num
"raw"
列表对象,哈希对象,集合对象
列表对象
列表对象的编码可以是ziplist(压缩列表作为底层实现)或者linkedlist
127.0.0.1:6379> RPUSH numbers 1 "three" 5
(integer) 3
127.0.0.1:6379> OBJECT ENCODING numbers
"ziplist"
字符串对象是Redis五种类型对象中唯一一种会被其他四种对象嵌套的对象
满足以下条件时列表使用ziplist编码:
1)每个元素的字符串长度都小于64Byte
2)元素个数小于512个
不满足以上条件的都使用linkedlist编码
127.0.0.1:6379> RPUSH myList 1 "three" 5
(integer) 3
127.0.0.1:6379> OBJECT ENCODING mylist
"ziplist"
127.0.0.1:6379> RPUSH myList "wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww"
(integer) 4
127.0.0.1:6379> OBJECT ENCODING myList
"linkedlist"
哈希对象
哈希对象的编码可以是ziplist或者hashtable
当键值对加入哈希对象时,先将键Push到ziplist表尾,再将值Push到表尾 : 键---值---键---值
有序集合对象
127.0.0.1:6379> HSET myHash name "dxt00"
(integer) 1
127.0.0.1:6379> HSET myHash age 18
(integer) 1
127.0.0.1:6379> HSET myHash career "Programmer"
(integer) 1
127.0.0.1:6379> HGET myHash name
"dxt00"
127.0.0.1:6379> HGET myHash age
"18"
127.0.0.1:6379> HGET myHash career
"Programmer"
满足以下条件时哈希对象使用ziplist编码:
1)所有键值对的键和值的字符串长度都小于64Byte
2)键值对个数小于512个
不满足以上条件的都使用hashtable编码
127.0.0.1:6379> EVAL "for i=1, 512 do redis.call('HSET', KEYS[1], i,i)end" 1 "myHash"
(nil)
127.0.0.1:6379> HLEN myHash
(integer) 515
127.0.0.1:6379> OBJECT ENCODING myHash
"hashtable"
集合对象
集合对象编码可以是inset或者hashtable
只有集合元素全是整数时,才用intset编码
127.0.0.1:6379> SADD mySET 1 3 5
(integer) 3
127.0.0.1:6379> OBJECT ENCODING mySET
"intset"
127.0.0.1:6379> SADD mySET "seven"
(integer) 1
127.0.0.1:6379> OBJECT ENCODING mySET
"hashtable"
有序集合对象
有序集合对象编码可以是ziplist或者skiplist
一个集合元素包含:member和score
每个集合元素使用两个紧挨着的ziplist节点保存,分别保存元素的成员(member)和分数(score)
127.0.0.1:6379> ZADD myZSET 8.5 apple 3.0 banana 7.0 cherry
(integer) 3
127.0.0.1:6379> OBJECT ENCODING myZSET
"ziplist"
skiplist
typedef struct zset
{
zskiplist *zsl;
dict *dict;
};
zsl跳表
按分值从小到大保存了所有集合元素。每个跳表节点是一个集合元素,跳表节点的object属性保存了元素成员(member), 跳表的score属性保存了元素的分值。
dict 为成员到分值的映射
///ZSET命令// p81
ZRANK 返回元素成员在跳表的排名
ZRANGE 从表头到表尾遍历跳表,返回给的索引内的所有元素
有序集合元素少于128个
元素成员长度都小于64Byte时 用ziplist
否则用skiplist
127.0.0.1:6379> EVAL "for i=1,128 do redis.call('ZADD',KEYS[1],i,i) end" 1 myZSET
(nil)
127.0.0.1:6379> ZCARD myZSET
(integer) 131
127.0.0.1:6379> OBJECT ENCODING myZSET
"skiplist"
对象的空转时长 p87
redisObject除了 type,encoding,ptr,refcount四个属性以外
还包含一个lru属性-->记录了对象最后一次被命令程序访问的时间
typedef struct redisObject
{
usingned lru:22;
}robj;
空转时长:IdleTime = 当前时间- lru
127.0.0.1:6379> SET msg "hello"
OK
127.0.0.1:6379> OBJECT IDLETIME msg
(integer) 12
127.0.0.1:6379> OBJECT IDLETIME msg
(integer) 15
127.0.0.1:6379> OBJECT IDLETIME msg
(integer) 17