写点什么

redis 编码及数据结构

  • 2022 年 5 月 15 日
  • 本文字数:1977 字

    阅读完需:约 6 分钟

(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



  1. "username"



  1. "lisi"



  1. "password"



  1. "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



  1. "b"



  1. "a"



  1. "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



  1. "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



  1. "lisi"



  1. "zhangsan"



  1. "wangwu"


127.0.0.1:6379> zrange mysort 0 -1 withscores



  1. "zhangsan"



  1. "60"



  1. "wangwu"



  1. "80"



  1. "lisi"



  1. "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:标记压缩列表的末端


![](https://img-blog.csdnimg.c 《一线大厂 Java 面试题解析+后端开发学习笔记+最新架构讲解视频+实战项目源码讲义》无偿开源 威信搜索公众号【编程进阶路】 n/20200927132535200.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0hOVV9Dc2VlX3dqdw==,size_16,color_FFFFFF,t_70)


linkedlist 是一个双向链表,但头节点的前驱指针指向的是 null,尾节点的后继指针指向的是 null,不是一个环形链表


2.6?集合类型内部实现——intset & hashtable 编码

用户头像

还未添加个人签名 2022.04.13 加入

还未添加个人简介

评论

发布
暂无评论
redis编码及数据结构_Java_爱好编程进阶_InfoQ写作社区