redis 编码及数据结构
(integer) 1
127.0.0.1:6379> hset myhash password 123
(integer) 1
2. 获取:
hget key field: 获取指定的 field 对应的值
127.0.0.1:6379> hget myhash username
"lisi"
hgetall key:获取所有的 field 和 value
127.0.0.1:6379> hgetall myhash
"username"
"lisi"
"password"
"123"
3. 删除: hdel key field
127.0.0.1:6379> hdel myhash username
(integer) 1
1.3.4?列表类型 list
可以添加一个元素到列表的头部(左边)或者尾部(右边)
1. 添加:
lpush key value: 将元素加入列表左表
rpush key value:将元素加入列表右边
127.0.0.1:6379> lpush myList a
(integer) 1
127.0.0.1:6379> lpush myList b
(integer) 2
127.0.0.1:6379> rpush myList c
(integer) 3
2. 获取:
lrange key start end :范围获取
127.0.0.1:6379> lrange myList 0 -1
"b"
"a"
"c"
3. 删除:
lpop key: 删除列表最左边的元素,并将元素返回
rpop key: 删除列表最右边的元素,并将元素返回
1.3.5?集合类型 set : 不允许重复元素
1. 存储:sadd key value
127.0.0.1:6379> sadd myset a
(integer) 1
127.0.0.1:6379> sadd myset a
(integer) 0
2. 获取:smembers key:获取 set 集合中所有元素
127.0.0.1:6379> smembers myset
"a"
3. 删除:srem key value:删除 set 集合中的某个元素
127.0.0.1:6379> srem myset a
(integer) 1
1.3.6?有序集合类型 sortedset
不允许重复元素,且元素有顺序.每个元素都会关联一个 double 类型的分数。redis 正是通过分数来为集合中的成员进行从小到大的排序。
1. 存储:zadd key score value
127.0.0.1:6379> zadd mysort 60 zhangsan
(integer) 1
127.0.0.1:6379> zadd mysort 50 lisi
(integer) 1
127.0.0.1:6379> zadd mysort 80 wangwu
(integer) 1
2. 获取:zrange key start end [withscores]
127.0.0.1:6379> zrange mysort 0 -1
"lisi"
"zhangsan"
"wangwu"
127.0.0.1:6379> zrange mysort 0 -1 withscores
"zhangsan"
"60"
"wangwu"
"80"
"lisi"
"500"
3. 删除:zrem key value
127.0.0.1:6379> zrem mysort lisi
(integer) 1
1.3.7?通用命令
1. keys * : 查询所有的键
2. type key : 获取键对应的 value 的类型
3. del key:删除指定的 key value
2?redis 编码及数据结构
==============
上面都是一些 redis 的基本入门级操作,接下来对于底层的分析是重点
2.1 redis 支持的数据类型

2.2?Redis 对象源码(3.0 版)

redisObject 类的属性有三个:
type:类型
encoding:对象的编码
int,embstr,raw,ht(哈希表),linkedlist,ziplist(连续空间),intset,skiplist(跳表)
ptr:指向底层实现数据结构的指针
type 可以看做是第一层、encoding 可以看做是第二层、ptr 可以看做是第三层,他们之间有一些对应关系。
2.3?Redis 对象类型——type(第一层)& encoding(第二层)

redis 对象的 key 都是 String 的,value 就是其支持的 5 种数据类型。我们可以用 TYPE 命令查看 value 的类型:

5 个数据类型与源码中的 8 个 encoding(编码)类型的对照关系(第一层和第二层对照):

之所以有这么多的对照关系是因为 redis 支持了针对不同应用场景来采用不同的数据结构,具有更大的灵活性。
我们可以用 OBJECT encoding 命令来查看相应的 encoding 类型:

2.4?字符串内部实现——int & raw & embstr

int 编码很简单,ptr 指向一个 int 型数据?

raw 的内部实现是 ptr 指向一个 sds(可以简单的理解为 redis 中实现的字符串)。
free 属性表示预留的空闲空间,len 表示实际字符串的长度,buf 是指向一个字符数组的指针。
预留空间:当申请的空间较小时,C 语言在申请 len 这么多的空间时会申请一份同样大小的预留空间。
惰性空间释放:删除数据时,free 的值会增加,而不是真正的把数据给释放掉

embstr 结构和 raw 的类似,只不过 ptr 不是指向 sds 的指针了,而是一个连续空间,ptr 后面紧跟着 sds 对象,所以查询会非常快,但这种方式并不适合存储大量数据。
选择编码格式的规则:
如果设置的数字是一个 long 类型的,那么其 encoding 就是 int
如果不是 long 类型表示的整形数字,那么用 raw 或者 embstr
长度小于等于 39 则是 embstr
长度大于 40 则是 raw
embstr 是一个只读的,如果要修改这样类型的数据,修改之后的结果会变为 raw


2.5?列表的内部实现——ziplist & linkedlist 编码

zlbytes:记录整个列表占用的内存字节数
zltail:记录列表尾节点距离压缩列表的起始地址有多少字节
zllen:包含的节点数量
zlend:标记压缩列表的末端

linkedlist 是一个双向链表,但头节点的前驱指针指向的是 null,尾节点的后继指针指向的是 null,不是一个环形链表
2.6?集合类型内部实现——intset & hashtable 编码
评论