面试:原来Redis的五种数据类型数底层结构是这样的
mhr18 2024-10-31 13:25 26 浏览 0 评论
关注我,可以获取最新知识、经典面试题以及微服务技术分享
在Redis中会涉及很多数据结构,比如SDS,双向链表、字典、压缩列表、整数集合等等。Redis会基于这些数据结构自定义一个对象系统,而且自定义的对象系统有很多好处。
通过对以下的Redis对象系统的学习,可以了解Redis设计原理以及初衷,为了我们在使用Redis的时候,更加能够理解到其原理和定位问题。
Redis 对象
Redis基于上述的数据结构自定义一个Object 系统,Object结构:
redisObject结构: typedef struct redisObject{ //类型 unsigned type:4; //编码 unsigned encoding:4; //指向底层实现数据结构的指针 void *ptr; ….. }
Object 系统包含五种Object:
- String:字符串对象
- List:列表对象
- Hash:哈希对象
- Set:集合对象
- ZSet:有序集合
Redis使用对象来表示数据库中的键和值,即每新建一个键值对,至少创建有两个对象,而且使用对象的具有以下好处:
- redis可以在执行命令前会根据对象的类型判断一个对象是否可以执行给定的命令
- 针对不同的使用场景,为对象设置不同的数据结构实现,从而优化对象的不同场景夏的使用效率
- 对象系统还可以基于引用计数计数的内存回收机制,自动释放对象所占用的内存,或者还可以让多个数据库键共享同一个对象来节约内存。
- redis对象带有访问时间记录信息,使用该信息可以进行优化空转时长较大的key,进行删除!
对象的ptr指针指向对象的底层现实数据结构,而这些数据结构由对象的encoding属性决定,对应关系:
编码常量 编码对应的底层数据结构 REDISENCODINGINT long类型的整数 REDISENCODINGEMBSTR embstr编码的简单动态字符串 REDISENCODINGRAW 简单动态字符串 REDISENCODINGHT 字典 REDISENCODINGLINKEDLIST 双向链表 REDISENCODINGZIPLIST 压缩列表 REDISENCODINGINTSET 整数集合 REDISENCODINGSKIPLIST 跳跃表和字典
每种Object对象至少有两种不同的编码,对应关系:
类型 编码 对象 String int 整数值实现 String embstr sds实现 <=39 字节 String
raw sds实现 > 39字节 List ziplist
压缩列表实现 List linkedlist 双端链表实现 Set intset
整数集合使用 Set hashtable
字典实现 Hash ziplist
压缩列表实现 Hash
hashtable 字典使用 Sorted set ziplist
压缩列表实现 Sorted set
skiplist 跳跃表和字典 String 对象
字符串对象编码可以int 、raw或者embstr,如果保存的值为整数值且这个值可以用long类型表示,使用int编码,其他编码类似。
比如:int编码的String Object
redis> set number 520 ok redis> OBJECT ENCODING number "int" String Object结构:
String 对象之间的编码转换
int编码的字符串对象和embstr编码的字符串对象在条件满足的情况下,会被转换为raw编码的字符串对象。
比如:对int编码的字符串对象进行append命令时,就会使得原来是int变为raw编码字符串
List对象
list对象可以为ziplist或者为linkedlist,对应底层实现ziplist为压缩列表,linkedlist为双向列表。
Redis>RPUSH numbers “Ccww” 520 1
用ziplist编码的List对象结构:
用linkedlist编码的List对象结构:
List对象的编码转换:
当list对象可以同时满足以下两个条件时,list对象使用的是ziplist编码:
- list对象保存的所有字符串元素的长度都小于64字节
- list对象保存的元素数量小于512个,
- 不能满足这两个条件的list对象需要使用linkedlist编码。
Hash对象
Hash对象的编码可以是ziplist或者hashtable其中,ziplist底层使用压缩列表实现:
- 保存同一键值对的两个节点紧靠相邻,键key在前,值vaule在后
- 先保存的键值对在压缩列表的表头方向,后来在表尾方向
hashtable底层使用字典实现,Hash对象种的每个键值对都使用一个字典键值对保存:
- 字典的键为字符串对象,保存键key
- 字典的值也为字符串对象,保存键值对的值
比如:HSET命令
redis>HSET author name "Ccww" (integer) redis>HSET author age 18 (integer) redis>HSET author sex "male" (integer) ziplist的底层结构:
hashtable底层结构:
Hash对象的编码转换:
当list对象可以同时满足以下两个条件时,list对象使用的是ziplist编码:
- list对象保存的所有字符串元素的长度都小于64字节
- list对象保存的元素数量小于512个,
- 不能满足这两个条件的hash对象需要使用hashtable编码
Note:这两个条件的上限值是可以修改的,可查看配置文件hash-max-zaiplist-value和hash-max-ziplist-entries
Set对象:
Set对象的编码可以为intset或者hashtable
- intset编码:使用整数集合作为底层实现,set对象包含的所有元素都被保存在intset整数集合里面
- hashtable编码:使用字典作为底层实现,字典键key包含一个set元素,而字典的值则都为null
inset编码Set对象结构:
redis> SAD number 1 3 5
hashtable编码Set对象结构:
redis> SAD Dfruits “apple” "banana" " cherry"
Set对象的编码转换:
使用intset编码:
- set对象保存的所有元素都是整数值
- set对象保存的元素数量不超过512个
- 不能满足这两个条件的Set对象使用hashtable编码
ZSet对象
ZSet对象的编码 可以为ziplist或者skiplistziplist编码,每个集合元素使用相邻的两个压缩列表节点保存,一个保存元素成员,一个保存元素的分值,然后根据分数进行从小到大排序。
ziplist编码的ZSet对象结构:
Redis>ZADD price 8.5 apple 5.0 banana 6.0 cherry
skiplist编码的ZSet对象使用了zset结构,包含一个字典和一个跳跃表
Type struct zset{ Zskiplist *zsl; dict *dict; ... } skiplist编码的ZSet对象结构 
ZSet对象的编码转换
当ZSet对象同时满足以下两个条件时,对象使用ziplist编码
- 有序集合保存的元素数量小于128个
- 有序集合保存的所有元素的长度都小于64字节
- 不能满足以上两个条件的有序集合对象将使用skiplist编码。
Note:可以通过配置文件中zset-max-ziplist-entries和zset-max-ziplist-vaule
相关推荐
- Java培训机构,你选对了吗?(java培训机构官网)
-
如今IT行业发展迅速,不仅是大学生,甚至有些在职的员工都想学习java开发,需求量的扩大,薪资必定增长,这也是更多人选择java开发的主要原因。不过对于没有基础的学员来说,java技术不是一两天就能...
- 产品经理MacBook软件清单-20个实用软件
-
三年前开始使用MacBookPro,从此再也不想用Windows电脑了,作为生产工具,MacBook可以说是非常胜任。作为产品经理,值得拥有一台MacBook。MacBook是工作平台,要发挥更大作...
- RAD Studio(Delphi) 本月隆重推出新的版本12.3
-
#在头条记录我的2025#自2024年9月,推出Delphi12.2版本后,本月隆重推出新的版本12.3,RADStudio12.3,包含了Delphi12.3和C++builder12.3最...
- 图解Java垃圾回收机制,写得非常好
-
什么是自动垃圾回收?自动垃圾回收是一种在堆内存中找出哪些对象在被使用,还有哪些对象没被使用,并且将后者删掉的机制。所谓使用中的对象(已引用对象),指的是程序中有指针指向的对象;而未使用中的对象(未引用...
- Centos7 初始化硬盘分区、挂载(针对2T以上)添加磁盘到卷
-
1、通过命令fdisk-l查看硬盘信息:#fdisk-l,发现硬盘为/dev/sdb大小4T。2、如果此硬盘以前有过分区,则先对磁盘格式化。命令:mkfs.文件系统格式-f/dev/sdb...
- 半虚拟化如何提高服务器性能(虚拟化 半虚拟化)
-
半虚拟化是一种重新编译客户机操作系统(OS)将其安装在虚拟机(VM)上的一种虚拟化类型,并在主机操作系统(OS)运行的管理程序上运行。与传统的完全虚拟化相比,半虚拟化可以减少开销,并提高系统性能。虚...
- HashMap底层实现原理以及线程安全实现
-
HashMap底层实现原理数据结构:HashMap的底层实现原理主要依赖于数组+链表+红黑树的结构。1、数组:HashMap最底层是一个数组,称为table,它存放着键值对。2、链...
- long和double类型操作的非原子性探究
-
前言“深入java虚拟机”中提到,int等不大于32位的基本类型的操作都是原子操作,但是某些jvm对long和double类型的操作并不是原子操作,这样就会造成错误数据的出现。其实这里的某些jvm是指...
- 数据库DELETE 语句,还保存原有的磁盘空间
-
MySQL和Oracle的DELETE语句与数据存储MySQL的DELETE操作当你在MySQL中执行DELETE语句时:逻辑删除:数据从表中标记为删除,不再可见于查询结果物理...
- 线程池—ThreadPoolExecutor详解(线程池实战)
-
一、ThreadPoolExecutor简介在juc-executors框架概述的章节中,我们已经简要介绍过ThreadPoolExecutor了,通过Executors工厂,用户可以创建自己需要的执...
- navicat如何使用orcale(详细步骤)
-
前言:看过我昨天文章的同鞋都知道最近接手另一个国企项目,数据库用的是orcale。实话实说,也有快三年没用过orcale数据库了。这期间问题不断,因为orcale日渐消沉,网上资料也是真真假假,难辨虚...
- 你的程序是不是慢吞吞?GraalVM来帮你飞起来性能提升秘籍大公开
-
各位IT圈内外的朋友们,大家好!我是你们的老朋友,头条上的IT技术博主。不知道你们有没有这样的经历:打开一个软件,半天没反应;点开一个网站,图片刷不出来;或者玩个游戏,卡顿得想砸电脑?是不是特别上火?...
- 大数据正当时,理解这几个术语很重要
-
目前,大数据的流行程度远超于我们的想象,无论是在云计算、物联网还是在人工智能领域都离不开大数据的支撑。那么大数据领域里有哪些基本概念或技术术语呢?今天我们就来聊聊那些避不开的大数据技术术语,梳理并...
- 秒懂列式数据库和行式数据库(列式数据库的特点)
-
行式数据库(Row-Based)数据按行存储,常见的行式数据库有Mysql,DB2,Oracle,Sql-server等;列数据库(Column-Based)数据存储方式按列存储,常见的列数据库有Hb...
- AMD发布ROCm 6.4更新:带来了多项底层改进,但仍不支持RDNA 4
-
AMD宣布,对ROCm软件栈进行了更新,推出了新的迭代版本ROCm6.4。这一新版本里,AMD带来了多项底层改进,包括更新改进了ROCm的用户空间库和AMDKFD内核驱动程序之间的兼容性,使其更容易...
你 发表评论:
欢迎- 一周热门
- 最近发表
- 标签列表
-
- oracle位图索引 (74)
- oracle批量插入数据 (65)
- oracle事务隔离级别 (59)
- oracle 空为0 (51)
- oracle主从同步 (56)
- oracle 乐观锁 (53)
- redis 命令 (78)
- php redis (88)
- redis 存储 (66)
- redis 锁 (69)
- 启动 redis (66)
- redis 时间 (56)
- redis 删除 (67)
- redis内存 (57)
- redis并发 (52)
- redis 主从 (69)
- redis 订阅 (51)
- redis 登录 (54)
- redis 面试 (58)
- 阿里 redis (59)
- redis 搭建 (53)
- redis的缓存 (55)
- lua redis (58)
- redis 连接池 (61)
- redis 限流 (51)