Redis的五种数据结构的内部编码
type命令实际返回的就是当前键的数据结构类型,它们分别是:string(字符串)、hash(哈希)、
list(列表)、set(集合)、zset(有序集合),但这些只是Redis对外的数据结构。

实际上每种数据结构都有自己底层的内部编码实现,而且是多种实现,这样Redis会在合适的场景选择合适的内部编码。
可以看到每种数据结构都有两种以上的内部编码实现,例如string数据结构就包含了raw、int和embstr三种内部编码。
同时,有些内部编码可以作为多种外部数据结构的内部实现,例如ziplist就是hash、list和zset共有的内部编码。
我们可以通过object encoding命令查询内部编码:
127.0.0.1:> set set: hello
OK
127.0.0.1:> object encoding set:
"embstr"
127.0.0.1:> hset user: name kebi
(integer)
127.0.0.1:> object encoding user:
"ziplist"
可以看到键set:1对应值的内部编码是“embstr”,键user:1对应值的内部编码是“ziplist”。
Redis这样设计有两个好处:
第一,可以改进内部编码,而对外的数据结构和命令没有影响,这样一旦开发开发出优秀的内部编码,无需改动外部数据结构和命令。
第二,多种内部编码实现可以在不同场景下发挥各自的优势。例如ziplist比较节省内存,但是在列表元素比较多的情况下,性能会有所下降,
这时候Redis会根据配置选项将列表类型的内部实现转换为linkedlist。
下面会分别介绍5种数据结构的内部编码方式。
1.字符串的内部编码
字符串类型的内部编码有3种:
- int:8个字节的长整型。
- embstr:小于等于39个字节的字符串。
- raw:大于39个字节的字符串。
Redis会根据当前值的类型和长度决定使用内部编码实现。
(1)整数类型示例如下:
127.0.0.1:> set str
OK
127.0.0.1:> object encoding str
"int"
(2)短字符串示例如下:
127.0.0.1:> set str "hello world"
OK
127.0.0.1:> object encoding str
"embstr"
(3)长字符串示例如下:
127.0.0.1:> set str "Tranquil,unbeatable to the outside. -- yangming" #“凝聚于内,无敌于外。--王阳明”
OK
127.0.0.1:> object encoding str
"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:
127.0.0.1:> hmset user: name kebi age
OK
127.0.0.1:> object encoding user:
"ziplist"
(2)当有value大于64个字节,内部编码会由ziplist变为hashtable:
127.0.0.1:> hmset user: info "沐春风,惹一身红尘;望秋月,化半缕轻烟。顾盼间乾坤倒转,一霎时沧海桑田。方晓,弹指红颜老,刹那芳华逝。"
127.0.0.1:> object encoding user:
"hashtable"
(3)当field个数超过512,内部编码也会由ziplist变为hashtable:
...待插入内容...
注意:当一个哈希的编码由ziplist变为hashtable的时候,即使在替换掉所有值,它一直都会是hashtable类型。
3.列表的内部编码
列表类型的内部编码有两种:
- ziplist(压缩列表):当哈希类型元素个数小于hash-max-ziplist-entries配置(默认512个)
同时所有值都小于hash-max-ziplist-value配置(默认64个字节)时,Redis会使用ziplist作为哈希的内部实现。
- linkedlist(链表):当列表类型无法满足ziplist的条件时,Redis会使用linkedlist作为列表的内部实现。
下面演示列表类型的内部编码,以及相应的变化:
(1)当元素个数较少且没有大元素时,内部编码为ziplist:
127.0.0.1:> rpush list: a b c
(integer)
127.0.0.1:> object encoding list:
"ziplist"
(2)当元素个数超过512个,内部编码变为linkedlist:
127.0.0.1:>lpush setkey ...
OK
127.0.0.1:> object encoding listkey
"linkedlist"
(3)当某个元素超过64个字节,内部编码也会变为linkedlist:
127.0.0.1:> rpush list: a b "我不再说话,不再思索,但无尽的爱从灵魂中升起,我将远行,走得很远,如同一个吉普塞人,穿过大自然——幸福得如有一位女子同行。"
(integer)
127.0.0.1:> object encoding list:
"linkedlist"
#只能升级,不能自动变回ziplist类型
4.集合的内部编码
集合类型的内部编码有两种:
- intset(整数集合):当集合中的元素都是整数且元素个数小于set-max-intset-entries配置(默认512个)时,
Redis会选用intset来作为集合内部实现,从而减少内存的使用。
- hashtable(哈希表):当集合类型无法满足intset的条件时,Redis会使用hashtable作为集合的内部实现。
下面用示例来说明:
(1)当元素个数较少且都为整数时,内部编码为intset:
127.0.0.1:> sadd setkey
(integer)
127.0.0.1:> object encoding setkey
"intset"
(2)当元素个数超过512个,内部编码变为hastable:
127.0.0.1:>sadd setkey2 ...
OK
127.0.0.1:> object encoding setkey2
"hashtable"
(3)当某个元素不为整数时,内部编码也会变为hashtable:
127.0.0.1:> sadd setkey3 a b c
(integer)
127.0.0.1:> object encoding setkey2
"hashtable"
5.有序集合的内部编码
有序集合类型的内部编码有两种
- ziplist(压缩列表):当有序集合的元素个数小于zset-max-ziplist-entries配置(默认128个)
同时每个元素的值小于zset-max-ziplist-value配置(默认64个字节)时,Redis会用ziplist来作为有序集合的内部实现,ziplist可以有效减少内存使用。
- skiplist(跳跃表):当ziplist条件不满足时,有序集合会使用skiplist作为内部实现,因为此时zip的读写效率会下降。
下面用示例来说明:
(1)当元素个数较少且每个元素较小时,内部编码为ziplist:
127.0.0.1:> zadd zsetkey a b c
(integer)
127.0.0.1:> object encoding zsetkey
"ziplist"
(2)当元素个数超过128个,内部编码变为skiplist:
...待输入...
(3)当某个元素大于64个字节时,内部编码也会变为skiplist:
127.0.0.1:> zadd zsetkey a b '闪烁的太阳已越过高傲的山峦,幽谷中的光点有若泡沫浮起。'
(integer)
127.0.0.1:> object encoding zsetkey
"skiplist"
Redis的五种数据结构的内部编码的更多相关文章
- Redis入门到高可用(四)—— Redis的五种数据结构的内部编码
Redis的五种数据结构的内部编码
- Redis的五种数据结构
Redis支持持久化只是它的一件武器,它提供了多达5种数据存储方式: 一 string(字符串) string是最简单的类型,你可以理解成与Memcached一模一样的类型,一个key对应一个val ...
- Redis五种数据结构(Windows Server)
1.Redis的五种数据结构 这里推荐大家在命名redis的key的时候最好的加上前缀,并且使用 :来分割前缀 ,这里在使用可视化工具查看的时候就比较好区分,比如我的的前缀是 Demo:test:(一 ...
- 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. ...
- 高可用Redis(一):通用命令,数据结构和内部编码,单线程架构
1.通用API 1.1 keys命令和dbsize命令 keys * 遍历所有key keys [pattern] 遍历模式下所有的key dbsize 计算Redis中所有key的总数 例子: 12 ...
- redis 五种数据结构详解(string,list,set,zset,hash)
redis 五种数据结构详解(string,list,set,zset,hash) Redis不仅仅支持简单的key-value类型的数据,同时还提供list,set,zset,hash等数据结构的存 ...
- Redis(1)---五种数据结构
五种数据结构 一.全局key操作 --删 flushdb --清空当前选择的数据库 del mykey mykey2 --删除了两个 Keys --改 --将当前数据库中的 mysetkey 键移入到 ...
- redis 五种数据结构详解(string,list,set,zset,hash),各种问题综合
redis 五种数据结构详解(string,list,set,zset,hash) https://www.cnblogs.com/sdgf/p/6244937.html redis 与 spring ...
- 【Redis】redis 五种数据结构详解(string,list,set,zset,hash)
redis 五种数据结构详解(string,list,set,zset,hash) Redis不仅仅支持简单的key-value类型的数据,同时还提供list,set,zset,hash等数据结构的存 ...
随机推荐
- 重写MFC窗口上的关闭按钮事件(SDI, MDI, Dialog)
This piece of code demonstrate how to override WM_CLOSE event. 点击窗口关闭按钮,触发相关事件! 有时候,在MFC程序退出之前,我们通常会 ...
- MDU某产品OMCI模块代码质量现状分析
说明 本文参考MDU系列某产品OMCI模块现有代码,提取若干实例以说明目前的代码质量,亦可作为甄别不良代码的参考. 本文旨在就事论事,而非否定前人(没有前人的努力也难有后人的进步).希望以史为鉴,不破 ...
- ATM技术基本原理
1 术语.定义和缩略语 1.1 术语.定义 术语/定义 说 明 ATM层 位于B-ISDN/ATM网络协议参考模型的第二层,完成交换.路由选择和信元复用功能.ATM层的基本处理单位是信元. AA ...
- 学了Python可以做什么工作
学了Python可以做什么工作 用 Python 写爬虫 据我所知很多初学 Python 的人都是使用它编写爬虫程序.小到抓取一个小黄图网站,大到一个互联网公司的商业应用.通过 Python 入门爬虫 ...
- css笔记 - transition学习笔记(二)
开始把7,8月份学的css整理一下 transition过渡 1. CSS transition transition过渡 :用于当元素 从一种样式变换为另一种样式 时为元素添加效果. 2. tran ...
- 【ORACLE 】查询被锁住的对象,并结束其会话
使用Oracle时,发现有表被锁,又不知道是谁(或者哪个程序)锁的,怎么办 ? 两步走: 1.查找出被锁对象的会话ID和序列号 执行如下SQL: -- 查询出被锁对象,并提供 kill 脚本 SELE ...
- linux中删除文件名称乱码
在最近的操作中发现一些上传的文件有乱码,更改几次都无法正常转换到中文.下面给出正确的解决方案: 使用 ls -i 或者 ls -inum 查找出文件id号(红色字体) [root@localhost ...
- Artech的MVC4框架学习——第三章controller的激活
第一当目标controller的名称通过URL路由被解析出来后,asp.net mvc利用 ControllerBuilder 注册 ControllerFactory ,根据名称实现对目标contr ...
- mongodb的远程访问
1,centos6上安装mongodb:2,新建可以远程访问的用户,以便可以远程访问: [root@localhost ~]# cd /usr/local/mongodb/bin/ [root@loc ...
- Dockerfile创建镜像
Dockerfile是一个文本格式的配置文件,用户可以使用Dockerfile来快速创建自定义的镜像. Dockerfile由一行行命令语句组成,并且支持易#开头的注释行. 一般而言Dockerfil ...