当前位置: 首页 > news >正文

redis五种数据类型内部构造

1、String

1、实现方式:

1、RAW编码方式:默认的,redisObject指针指向SDS

2、EMBSTR编码方式:redisObject和SDS形成数组

3、INT编码方式:直接用redisObject指针存储,指针是无符号的8位

StringRedis中最常见的数据存储类型:

1、 基本编码 方式是 RAW ,基于简单动态字符串( SDS )实现, 存储上限 512mb
2、 如果存储的 SDS 长度小于44字 节,则会采用 EMBSTR 编码,此时 object head与SDS是一段连续空间 申请内存 只需 调用一次 内存分配函数,效率更高。
3、 如果 存储 字符串 整数值 ,并且大小在 LONG_MAX范围 内,则会采用 INT 编码:直接将数据保存在 RedisObject ptr 指针位置(刚好 8 字节),不再需要 SDS 了。

1、下图是RAW编码方式:

基本编码 方式是 RAW ,基于简单动态字符串( SDS )实现, 存储上限 512mb

2、下图是EMBSTR编码方式

如果存储的SDS长度小于44字节,则会采用EMBSTR编码,此时object headSDS是一段连续空间。申请内存时只需要调用一次内存分配函数,效率更高。

 3、下图是INT编码方式

如果存储的字符串是整数值,并且大小在LONG_MAX范围内,则会采用INT编码:直接将数据保存在RedisObjectptr指针位置(刚好8字节),不再需要SDS了。

 总结:

可以看到String具有的三种转换形式

 测试

 2、List

2、实现方式:

1、3.2版本之前,ZipListLinkedList来实现List

2、3.2版本之后,QuickList实现

RedisList类型可以从首、尾操作列表中的元素:

哪一个数据结构能满足上述特征?

LinkedList :普通链表,可以从双端访问, 内存占用较高 ,内存 碎片较多
ZipList :压缩列表,可以从双端访问, 内存占用低 ,存储 上限低
QuickList LinkedList + ZipList ,可以从双端访问,内存 占用较低 ,包含多个 ZipList 存储上限高

RedisList结构类似一个双端链表,可以从首、尾操作列表中的元素:

3.2版本之前Redis采用ZipListLinkedList来实现List,当元素数量小于512并且元素大小小于64字节时采用ZipList编码超过则采用LinkedList编码

3.2版本之后Redis统一采用QuickList来实现List

 

 

 3、Set

3、实现方式:

1、Dict实现,value都存储null

2、如果都是整数,那么用Inset结构

SetRedis中的单列集合,满足下列特点:

1、 不保证有序性
2、 保证 元素唯一 ( 可以判断元素是否存在 )
3、 求交集、并集、差集

可以看出,Set对查询元素的效率要求非常高,思考一下,什么样的数据结构可以满足?

1、 HashTable ,也就是 Redis 中的 Dict ,不过 Dict 是双列集合(可以存键、值对)
2、 为了查询效率和唯一性, set 采用 HT 编码( Dict )。 Dict 中的 key 用来存储元素, value统一为null。
3、 当存储的 所有数据 是整数 ,并且 元素数量 不超过 set-max-intset-entries时 Set 会采用 IntSet编码 ,以节省内存。
源码:
1、下图解释传入的数据不同set底层创建的方式也是不同的
2、下面是添加元素

 

 展示

 

4、ZSet

4、实现方式:

1、SkipList(有序)和HT(键值查找)结合构成

2、ZipList,两个entry构成一个,ele为键,score为值

ZSet也就是SortedSet,其中每一个元素都需要指定一个score值member值

1、可以根据score值排序

2、member必须唯一

3、可以根据member查询分数

 

因此,zset底层数据结构必须满足键值存储、键必须唯一、可排序这几个需求。之前学习的哪种编码结构可以满足?

1、 SkipList 可以排序 ,并且可以同时 存储score和ele值 member
2、 HT Dict 可以 键值存储 ,并且可以 根据key找value,key==ele,value==score

 

 

 源码分析

元素数量不多时,HT和SkipList优势不明显,而且更耗内存。因此zset还会采用ZipList结构来节省内存,不过需要同时满足两个条件

元素数量小于zset_max_ziplist_entries,默认值128

每个元素小于zset_max_ziplist_value字节,默认值64

ziplist本身没有排序功能,而且没有键值对的概念,因此需要zset通过编码实现

1、ZipList连续内存,因此score和element紧挨在一起的两个entry element在前score在后2、score越小接近队首score越大越接近队尾,按照score值升序排列

从下面代码可以看到

1、zset实现的两种方式

 2、下面的是添加Zset的方法

 

 5、Hash

5、实现方式:

本质和zset是一样的

1、直接用dict实现,去除跳表

2、使用ZipList实现

Hash结构与Redis中的Zset非常类似:

1、 都是键值存储
2、 都需求根据键获取值
3、 键必须唯一

区别如下:

1、zset键是member值是scorehash的键和值都是任意值

2、zset要根据score排序hash无需排序

因此,Hash底层采用的编码与Zset也基本一致,只需要把排序有关的SkipList去掉即可:

 因此,Hash底层采用的编码与Zset也基本一致,只需要把排序有关的SkipList去掉即可:

1、Hash结构默认采用ZipList编码,用以节省内存。 ZipList中相邻的两个entry 分别保存fieldvalue

2、数据量较大时,Hash结构会转为HT编码,也就是Dict,触发条件有两个:

ZipList中的元素数量超过hash-max-ziplist-entries(默认512

ZipList中的任意entry大小超过hash-max-ziplist-value(默认64字节

hash对应的两种结构

 

 

 

 源码展示

 

 

相关文章:

  • 基于Vue+Element UI+SSM+SpringCloud的员工管理系统
  • LeetCode刷题---二分查找巩固
  • 简单概述理解vue的MVVM模型
  • 24、Java——银行存款取款系统(对象+集合)
  • Python 集合
  • 【DS】5.二叉树大总结!
  • 攻防世界 web2
  • 机器人运动学标定:基于公垂线模型的指数积标定——减少标定参数,避免过度约束
  • 机器学习模型的集成方法总结:Bagging, Boosting, Stacking, Voting, Blending
  • 全志 Melis-4.0(rt-thread内核) 环境搭建与初步编译介绍
  • JUC 中的线程池入门(其实没有那么难)
  • 派福利!通过 Azure 零成本进入 CUDA 编程
  • 10.6日作业
  • Mybatis,动态代理方式的CRUD
  • Linux 进程管理类
  • 【mysql】环境安装、服务启动、密码设置
  • 【个人向】《HTTP图解》阅后小结
  • 【刷算法】求1+2+3+...+n
  • 2017-09-12 前端日报
  • canvas 绘制双线技巧
  • Gradle 5.0 正式版发布
  • If…else
  • Java-详解HashMap
  • Laravel 实践之路: 数据库迁移与数据填充
  • leetcode386. Lexicographical Numbers
  • SQLServer插入数据
  • 阿里中间件开源组件:Sentinel 0.2.0正式发布
  • 关于springcloud Gateway中的限流
  • 码农张的Bug人生 - 初来乍到
  • 想晋级高级工程师只知道表面是不够的!Git内部原理介绍
  • 正则表达式
  • 仓管云——企业云erp功能有哪些?
  • 扩展资源服务器解决oauth2 性能瓶颈
  • 说说我为什么看好Spring Cloud Alibaba
  • ​一些不规范的GTID使用场景
  • (7)STL算法之交换赋值
  • (9)STL算法之逆转旋转
  • (delphi11最新学习资料) Object Pascal 学习笔记---第7章第3节(封装和窗体)
  • (七)MySQL是如何将LRU链表的使用性能优化到极致的?
  • (一)UDP基本编程步骤
  • (幽默漫画)有个程序员老公,是怎样的体验?
  • (原創) 未来三学期想要修的课 (日記)
  • (转)jQuery 基础
  • (转)人的集合论——移山之道
  • (转贴)用VML开发工作流设计器 UCML.NET工作流管理系统
  • ***php进行支付宝开发中return_url和notify_url的区别分析
  • **PHP二维数组遍历时同时赋值
  • .NET 使用 JustAssembly 比较两个不同版本程序集的 API 变化
  • .net实现客户区延伸至至非客户区
  • .one4-V-XXXXXXXX勒索病毒数据怎么处理|数据解密恢复
  • /usr/bin/perl:bad interpreter:No such file or directory 的解决办法
  • /var/lib/dpkg/lock 锁定问题
  • [ vulhub漏洞复现篇 ] AppWeb认证绕过漏洞(CVE-2018-8715)
  • [51nod1610]路径计数
  • [android]-如何在向服务器发送request时附加已保存的cookie数据