redis 各种数据结构的encoding实现


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

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

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

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

我们可以通过object encoding命令查询内部编码:
127.0.0.1:6379> set set:1 hello
OK
127.0.0.1:6379> object encoding set:1
"embstr"
127.0.0.1:6379> hset user:1 name kebi
(integer) 1
127.0.0.1:6379> object encoding user:1
"ziplist"
 
可以看到键set:1对应值的内部编码是“embstr”,键user:1对应值的内部编码是“ziplist”。

Redis这样设计有两个好处:

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

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

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

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

1.字符串的内部编码

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

int:8个字节的长整型。

embstr:小于等于39个字节的字符串。

raw:大于39个字节的字符串。\

  • Redis会根据当前值的类型和长度决定使用内部编码实现。
(1)整数类型示例如下:
127.0.0.1:6379> set str 1234567
OK
127.0.0.1:6379> object encoding str
"int"
 
(2)短字符串示例如下:
127.0.0.1:6379> set str "hello world"
OK
127.0.0.1:6379> object encoding str
"embstr"
 
(3)长字符串示例如下:
127.0.0.1:6379> set str "Tranquil,unbeatable to the outside. -- yangming"  #“凝聚于内,无敌于外。--王阳明”
OK
127.0.0.1:6379> 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:6379> hmset user:2 name kebi age 26
OK
127.0.0.1:6379> object encoding user:2
"ziplist"
 
(2)当有value大于64个字节,内部编码会由ziplist变为hashtable:
127.0.0.1:6379> hmset user:1 info "沐春风,惹一身红尘;望秋月,化半缕轻烟。顾盼间乾坤倒转,一霎时沧海桑田。方晓,弹指红颜老,刹那芳华逝。"
127.0.0.1:6379> object encoding user:1
"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:6379> rpush list:2 a b c
(integer) 3
127.0.0.1:6379> object encoding list:2
"ziplist"
 
(2)当元素个数超过512个,内部编码变为linkedlist:
127.0.0.1:6379>lpush setkey 1 2 3 ... 513
OK
127.0.0.1:6379> object encoding listkey
"linkedlist"
 
(3)当某个元素超过64个字节,内部编码也会变为linkedlist:
127.0.0.1:6379> rpush list:1 a b "我不再说话,不再思索,但无尽的爱从灵魂中升起,我将远行,走得很远,如同一个吉普塞人,穿过大自然——幸福得如有一位女子同行。"
(integer) 6
127.0.0.1:6379> object encoding list:1
"linkedlist" - #只能升级,不能自动变回ziplist类型
 
4.集合的内部编码

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

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

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

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

  • 下面用示例来说明:
(1)当元素个数较少且都为整数时,内部编码为intset:
127.0.0.1:6379> sadd setkey 2 3 4 5
(integer) 4
127.0.0.1:6379> object encoding setkey
"intset"
 
(2)当元素个数超过512个,内部编码变为hastable:
127.0.0.1:6379>sadd setkey2 1 2 3 4 5 6 7...  511 512 513
OK
127.0.0.1:6379> object encoding setkey2
"hashtable"
 
(3)当某个元素不为整数时,内部编码也会变为hashtable:
127.0.0.1:6379> sadd setkey3 a b c
(integer) 3
127.0.0.1:6379> 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:6379> zadd zsetkey 50 a 60 b 30 c
(integer) 3
127.0.0.1:6379> object encoding zsetkey
"ziplist"
 
(2)当元素个数超过128个,内部编码变为skiplist:
...待输入...
 
(3)当某个元素大于64个字节时,内部编码也会变为skiplist:
127.0.0.1:6379> zadd zsetkey 50 a 60 b 30 '闪烁的太阳已越过高傲的山峦,幽谷中的光点有若泡沫浮起。'
(integer) 1
127.0.0.1:6379> object encoding zsetkey
"skiplist"
 

————————————————————————————————

本文内容非本猿原创,只是在作者原文稍作修改。

————————————————————————————————

原文链接:https://blog.csdn.net/clypm/article/details/52312937

 

redis 各种数据结构的encoding实现的更多相关文章

  1. Redis基本数据结构总结之SET、ZSET和HASH

    Redis基本数据结构总结 前言 Redis的特点在于其读写速度特别快,因为是存储在内存中的,其非常适合于处理大数据量的情况:还有一个是其不同于其他的关系型数据库,Redis是非关系型数据库,也就是我 ...

  2. 聊一聊Redis的数据结构

    如果没有记错的话,应该是在两个月前把 我们经常看到此类的文章: Redis的五种数据结构 Redis的数据结构以及对应的使用场景 其实以数据结构这个词去说明Redis的String.Hash.List ...

  3. 你真的懂redis的数据结构了吗?redis内部数据结构和外部数据结构揭秘

    Redis有哪些数据结构? 字符串String.字典Hash.列表List.集合Set.有序集合SortedSet. 很多人面试时都遇到过这种场景吧? 其实除了上面的几种常见数据结构,还需要加上数据结 ...

  4. redis内部数据结构深入浅出

    最大感受,无论从设计还是源码,Redis都尽量做到简单,其中运用到的原理也通俗易懂.特别是源码,简洁易读,真正做到clean and clear, 这篇文章以unstable分支的源码为基准,先从大体 ...

  5. redis内部数据结构和外部数据结构揭秘

    Redis有哪些数据结构? 字符串String.字典Hash.列表List.集合Set.有序集合SortedSet. 很多人面试时都遇到过这种场景吧? 其实除了上面的几种常见数据结构,还需要加上数据结 ...

  6. redis各种数据结构使用场景

    一.redis 数据结构使用场景 原来看过 redisbook 这本书,对 redis 的基本功能都已经熟悉了,从上周开始看 redis 的源码.目前目标是吃透 redis 的数据结构.我们都知道,在 ...

  7. 你真的懂了redis的数据结构吗?redis内部数据结构和外部数据结构揭秘

    原文链接:https://mp.weixin.qq.com/s/hKpAxPE-9HJgV6GEdV4WoA Redis有哪些数据结构? 字符串String.字典Hash.列表List.集合Set.有 ...

  8. redis 基础数据结构实现

    参考文献 redis数据结构分析 Skip List(跳跃表)原理详解 redis 源码分析之内存布局 Redis 基础数据结构与对象 Redis设计与实现-第7章-压缩列表 在redis中构建了自己 ...

  9. 探索Redis设计与实现7:Redis内部数据结构详解——intset

    本文转自互联网 本系列文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查看 https://github.com/h2pl/Java-Tutorial ...

随机推荐

  1. 为什么互联网巨头们纷纷使用Git而放弃SVN?(内含Git核心命令与原理总结)

    写在前面 最近发现很多小伙伴对于工作中的一些基本工具的使用还不是很了解,比如:Git这个分布式的代码管理仓库,很多小伙伴就不是很了解,或者说不是很熟悉.甚至有些小伙伴都没听说过Git,就只会用个SVN ...

  2. 使用App Metrics实现性能监控

    App Metrics监控需要安装InfluxDB时序数据库和Grafana可视化分析工具 1.安装InfluxDB 下载地址:https://portal.influxdata.com/downlo ...

  3. docker自己部署一个项目

    老祖宗的话说得好呀:实践出真知 自己打个简单的镜像运行  遇到了一堆破问题 学习docker主要在菜鸟教程  https://www.runoob.com/docker/docker-containe ...

  4. nacos快速安装

    一 什么是 Nacos 服务注册中心和配置中心. 二 使用 下载和启动 使用有两种方式 1.自己下载源码编译 2.下载编译好的压缩包 我比较懒选择了第二种方式. 最新稳定版本 下载地址:https:/ ...

  5. 【征文活动】为自己发“声” —— 声网RTC征文大赛在园子里征稿

    2020年8月20日,声网Agora入驻园子的新楼盘--博客园品牌专区.9月,我们与声网Agora再度合作,「为自己发"声"- RTC 征文大赛」在园子里征稿. RTC(Real- ...

  6. 整合mybatis与spring

    认识mybatis-spring MyBatis-Spring 需要以下版本: . 如果使用 Maven 作为构建工具,仅需要在 pom.xml 中加入以下代码即可: <dependency&g ...

  7. Nginx【常见知识点速查】

    文章更新时间:2020/04/10 一.简介 定义:Nginx是一个高性能的HTTP和反向代理web服务器 作用: 反向代理 正向代理 负载均衡 HTTP静态资源服务器(动静分离) 二.正向代理与反向 ...

  8. 刷题[GWCTF 2019]你的名字

    解题思路 打开发现需要输入名字,猜测会有sql注入漏洞,测试一下发现单引号被过滤了,再fuzs下看看过滤了哪些 长度为1518和1519的都有过滤,测试一下,感觉不是sql注入了.那还有什么呢,考虑了 ...

  9. spring:spring再总结(ioc、aop、DI等)

    IOC(Inversion of Control),即"控制反转",不是一种技术而是一种思想 1.IOC的理解 Ioc意味着将你设计好的对象交给容器控制,而不是传统的在你的对象内部 ...

  10. JAVA基础之代码简洁之道

    引言 普通的工程师堆砌代码,优秀的工程师优雅代码,卓越的工程师简化代码.如何写出优雅整洁易懂的代码是一门学问,也是软件工程实践里重要的一环.--来自网络 背景 软件质量,不但依赖于架构及项目管理,更与 ...