type命令实际返回的就是当前键的数据结构类型,它们分别是:string(字符串)、hash(哈希)、

list(列表)、set(集合)、zset(有序集合),但这些只是Redis对外的数据结构。

实际上每种数据结构都有自己底层的内部编码实现,而且是多种实现,这样Redis会在合适的场景选择合适的内部编码。

可以看到每种数据结构都有两种以上的内部编码实现,例如string数据结构就包含了raw、int和embstr三种内部编码。

同时,有些内部编码可以作为多种外部数据结构的内部实现,例如ziplist就是hash、list和zset共有的内部编码。

我们可以通过object encoding命令查询内部编码:

  1. 127.0.0.1:> set set: hello
  2. OK
  3. 127.0.0.1:> object encoding set:
  4. "embstr"
  5. 127.0.0.1:> hset user: name kebi
  6. (integer)
  7. 127.0.0.1:> object encoding user:
  8. "ziplist"

可以看到键set:1对应值的内部编码是“embstr”,键user:1对应值的内部编码是“ziplist”。

Redis这样设计有两个好处:

第一,可以改进内部编码,而对外的数据结构和命令没有影响,这样一旦开发开发出优秀的内部编码,无需改动外部数据结构和命令。

第二,多种内部编码实现可以在不同场景下发挥各自的优势。例如ziplist比较节省内存,但是在列表元素比较多的情况下,性能会有所下降,

  这时候Redis会根据配置选项将列表类型的内部实现转换为linkedlist。

下面会分别介绍5种数据结构的内部编码方式。

1.字符串的内部编码

字符串类型的内部编码有3种:

  • int:8个字节的长整型。
  • embstr:小于等于39个字节的字符串。
  • raw:大于39个字节的字符串。

Redis会根据当前值的类型和长度决定使用内部编码实现。

(1)整数类型示例如下:

  1. 127.0.0.1:> set str
  2. OK
  3. 127.0.0.1:> object encoding str
  4. "int"

(2)短字符串示例如下:

  1. 127.0.0.1:> set str "hello world"
  2. OK
  3. 127.0.0.1:> object encoding str
  4. "embstr"

(3)长字符串示例如下:

  1. 127.0.0.1:> set str "Tranquil,unbeatable to the outside. -- yangming" #“凝聚于内,无敌于外。--王阳明”
  2. OK
  3. 127.0.0.1:> object encoding str
  4. "raw"

2.哈希的内部编码

哈希类型的内部编码有两种:

  • ziplist(压缩列表):当哈希类型元素个数小于hash-max-ziplist-entries配置(默认512个),

    同时所有值都小于hash-max-ziplist-value配置(默认64个字节)时,Redis会使用ziplist作为哈希的内部实现

    ziplist使用更加紧凑的结构实现多个元素的连续存储,所以在节省内存方面比hashtable更加优秀。

  • hashtable(哈希表):当哈希类型无法满足ziplist的条件时,Redis会使用hashtable作为哈希的内部实现。

    因为此时ziplist的读写效率会下降,而hashtable的读写时间复杂度为O(1)。

下面演示哈希类型的内部编码,及相应的变化。

(1)当field个数比较少且没有大的value时,内部编码为ziplist:

  1. 127.0.0.1:> hmset user: name kebi age
  2. OK
  3. 127.0.0.1:> object encoding user:
  4. "ziplist"

(2)当有value大于64个字节,内部编码会由ziplist变为hashtable:

  1. 127.0.0.1:> hmset user: info "沐春风,惹一身红尘;望秋月,化半缕轻烟。顾盼间乾坤倒转,一霎时沧海桑田。方晓,弹指红颜老,刹那芳华逝。"
  2. 127.0.0.1:> object encoding user:
  3. "hashtable"

(3)当field个数超过512,内部编码也会由ziplist变为hashtable:

  1. ...待插入内容...

注意:当一个哈希的编码由ziplist变为hashtable的时候,即使在替换掉所有值,它一直都会是hashtable类型。

3.列表的内部编码

列表类型的内部编码有两种:

  • ziplist(压缩列表):当哈希类型元素个数小于hash-max-ziplist-entries配置(默认512个)

    同时所有值都小于hash-max-ziplist-value配置(默认64个字节)时,Redis会使用ziplist作为哈希的内部实现。

  • linkedlist(链表):当列表类型无法满足ziplist的条件时,Redis会使用linkedlist作为列表的内部实现。

下面演示列表类型的内部编码,以及相应的变化:

(1)当元素个数较少且没有大元素时,内部编码为ziplist:

  1. 127.0.0.1:> rpush list: a b c
  2. (integer)
  3. 127.0.0.1:> object encoding list:
  4. "ziplist"

(2)当元素个数超过512个,内部编码变为linkedlist:

  1. 127.0.0.1:>lpush setkey ...
  2. OK
  3. 127.0.0.1:> object encoding listkey
  4. "linkedlist"

(3)当某个元素超过64个字节,内部编码也会变为linkedlist:

  1. 127.0.0.1:> rpush list: a b "我不再说话,不再思索,但无尽的爱从灵魂中升起,我将远行,走得很远,如同一个吉普塞人,穿过大自然——幸福得如有一位女子同行。"
  2. (integer)
  3. 127.0.0.1:> object encoding list:
  4. "linkedlist"

#只能升级,不能自动变回ziplist类型

4.集合的内部编码

集合类型的内部编码有两种:

  • intset(整数集合):当集合中的元素都是整数且元素个数小于set-max-intset-entries配置(默认512个)时,

    Redis会选用intset来作为集合内部实现,从而减少内存的使用。

  • hashtable(哈希表):当集合类型无法满足intset的条件时,Redis会使用hashtable作为集合的内部实现。

下面用示例来说明:

(1)当元素个数较少且都为整数时,内部编码为intset:

  1. 127.0.0.1:> sadd setkey
  2. (integer)
  3. 127.0.0.1:> object encoding setkey
  4. "intset"

(2)当元素个数超过512个,内部编码变为hastable:

  1. 127.0.0.1:>sadd setkey2 ...
  2. OK
  3. 127.0.0.1:> object encoding setkey2
  4. "hashtable"

(3)当某个元素不为整数时,内部编码也会变为hashtable:

  1. 127.0.0.1:> sadd setkey3 a b c
  2. (integer)
  3. 127.0.0.1:> object encoding setkey2
  4. "hashtable"

5.有序集合的内部编码

有序集合类型的内部编码有两种

  • ziplist(压缩列表):当有序集合的元素个数小于zset-max-ziplist-entries配置(默认128个)

    同时每个元素的值小于zset-max-ziplist-value配置(默认64个字节)时,Redis会用ziplist来作为有序集合的内部实现,ziplist可以有效减少内存使用。

  • skiplist(跳跃表):当ziplist条件不满足时,有序集合会使用skiplist作为内部实现,因为此时zip的读写效率会下降。

下面用示例来说明:

(1)当元素个数较少且每个元素较小时,内部编码为ziplist:

  1. 127.0.0.1:> zadd zsetkey a b c
  2. (integer)
  3. 127.0.0.1:> object encoding zsetkey
  4. "ziplist"

(2)当元素个数超过128个,内部编码变为skiplist:

  1. ...待输入...

(3)当某个元素大于64个字节时,内部编码也会变为skiplist:

  1. 127.0.0.1:> zadd zsetkey a b '闪烁的太阳已越过高傲的山峦,幽谷中的光点有若泡沫浮起。'
  2. (integer)
  3. 127.0.0.1:> object encoding zsetkey
  4. "skiplist"

Redis的五种数据结构的内部编码的更多相关文章

  1. Redis入门到高可用(四)—— Redis的五种数据结构的内部编码

    Redis的五种数据结构的内部编码

  2. Redis的五种数据结构

    Redis支持持久化只是它的一件武器,它提供了多达5种数据存储方式: 一  string(字符串) string是最简单的类型,你可以理解成与Memcached一模一样的类型,一个key对应一个val ...

  3. Redis五种数据结构(Windows Server)

    1.Redis的五种数据结构 这里推荐大家在命名redis的key的时候最好的加上前缀,并且使用 :来分割前缀 ,这里在使用可视化工具查看的时候就比较好区分,比如我的的前缀是 Demo:test:(一 ...

  4. 2.Redis五种数据结构

    2.Redis五种数据结构2.1 预备2.1.1 全局命令2.1.2 数据结构和内部编码2.1.3 单线程架构2.2 字符串2.2.1 命令2.2.2 内部编码2.2.3 典型使用场景2.3 哈希2. ...

  5. 高可用Redis(一):通用命令,数据结构和内部编码,单线程架构

    1.通用API 1.1 keys命令和dbsize命令 keys * 遍历所有key keys [pattern] 遍历模式下所有的key dbsize 计算Redis中所有key的总数 例子: 12 ...

  6. redis 五种数据结构详解(string,list,set,zset,hash)

    redis 五种数据结构详解(string,list,set,zset,hash) Redis不仅仅支持简单的key-value类型的数据,同时还提供list,set,zset,hash等数据结构的存 ...

  7. Redis(1)---五种数据结构

    五种数据结构 一.全局key操作 --删 flushdb --清空当前选择的数据库 del mykey mykey2 --删除了两个 Keys --改 --将当前数据库中的 mysetkey 键移入到 ...

  8. redis 五种数据结构详解(string,list,set,zset,hash),各种问题综合

    redis 五种数据结构详解(string,list,set,zset,hash) https://www.cnblogs.com/sdgf/p/6244937.html redis 与 spring ...

  9. 【Redis】redis 五种数据结构详解(string,list,set,zset,hash)

    redis 五种数据结构详解(string,list,set,zset,hash) Redis不仅仅支持简单的key-value类型的数据,同时还提供list,set,zset,hash等数据结构的存 ...

随机推荐

  1. codeforces水题100道 第十一题 Codeforces Round #143 (Div. 2) A. Team (brute force)

    题目链接:http://www.codeforces.com/problemset/problem/231/A题意:问n道题目当中有多少道题目是至少两个人会的.C++代码: #include < ...

  2. 【LeetCode OJ】Search Insert Position

    题目:Given a sorted array and a target value, return the index if the target is found. If not, return ...

  3. You have tried to change the API from what has been previously approved.

    需要修改frameworks/base/下的代码,请注意 :如果修改了Android原有API的 ,需要update frameworks/base/api/current.txt.否则编译被中断并出 ...

  4. 【cs229-Lecture11】贝叶斯统计正则化

    本节知识点: 贝叶斯统计及规范化 在线学习 如何使用机器学习算法解决具体问题:设定诊断方法,迅速发现问题 贝叶斯统计及规范化(防止过拟合的方法) 就是要找更好的估计方法来减少过度拟合情况的发生. 回顾 ...

  5. IIS7 windows 下安装PHP

    首先要下载 php for windows 这个软件,百度一搜一大把. 1.我安装的是5.3.22版,就以这个为例给大家解说一下. 安装就是下一步,下一步,到一个选项 IIS FastCGI 选这个! ...

  6. reserve和resize区别

    reserve是容器预留空间,但在空间内不真正创建元素对象,所以在没有添加新的对象之前,不能引用容器内的元素.加入新的元素时,要调用push_back()/insert()函数. resize是改变容 ...

  7. nagios监控报错 It appears as though you do not have permission to view...

    今天在安装完nagios后,通过nagios网页界面点击主机.服务.问题页面时.均报错,报错的内容都差不多.如点击服务,报错: It appears as though you do not have ...

  8. python pytest测试框架介绍四----pytest-html插件html带错误截图及失败重测机制

    一.html报告错误截图 这次介绍pytest第三方插件pytest-html 这里不介绍怎么使用,因为怎么使用网上已经很多了,这里给个地址给大家参考,pytest-html生成html报告 今天在这 ...

  9. vue--动态路由和get传值

    动态路由: <template> <div id="News"> <v-header></v-header> <hr> ...

  10. 记我的第一个python爬虫

    捣鼓了两天,终于完成了一个小小的爬虫代码.现在才发现,曾经以为那么厉害的爬虫,在自己手里实现的时候,也不过如此.但是心里还是很高兴的. 其实一开始我是看的慕课上面的爬虫教学视屏,对着视屏的代码一行行的 ...