首页 > 数据库 >Redis(九)五种数据类型的底层结构

Redis(九)五种数据类型的底层结构

时间:2023-08-13 09:55:09浏览次数:43  
标签:编码 存储 score 数据类型 元素 Redis 五种 HashTable 内存

Redis(九)五种数据类型的底层结构


1 string

​ string是redis中最常见的数据类型

  • 基本编码方式是RAW,基于简单动态字符串(SDS)实现,存储上限为512MB,此时的object head和SDS是两个独立的空间,是通过redisObject的buf指针指向的实际存储的SDS

    image-20230813080732884

  • 如果存储的SDS长度小于44字节,则采用EMBSTR编码,此时的object head和SDS是一段连续的内存空间,申请空间的时候只需要申请一次内存分配,效率更高。超过44字节,否则会自动变为RAW编码

    为什么采用小于44字节使用EMB编码?

    因为object head总共占用20字节,加上44字节后是64字节,正好是redis内存分配的一个分片大小,这样不容易造成内存碎片,因此使用string的时候,尽量不要超过44字节,否则会自动变为RAW编码

    image-20230813080747361

  • INT编码则是将数字转化为二进制直接存储到redisObject的ptr指针部分,占用8字节

    image-20230813080850226

2 list

  • 在3.2版本之前,redis采用ZipListLinkedList来实现的List,当元素个数小于512并且元素大小小于64字节的时候就采用ZiplList编码,超过则采用LinkedList编码

  • 在3.2版本之后,redis统一采用QuickList来实现list,实现原理:

    • 首先针对list的key和value各建立一个RedisObject,value的RedisObject包含:
      • type类型为list
      • encoding编码为QuickList
      • lru:最近一次使用时间
      • refcount:引用计数
      • ptr:指向实际存储的QuickList空间
    • 然后QuickList的节点通过前后指针连接成双向链表,每个QuickList节点的zip指针指向存放真实数据的压缩链表
    image-20230813083339446
1 为什么redis的list底层采用quickList?
  • 为了满足redis的list类型数据可以从首尾操作列表元素的特性,

  • 如果采用LinkedList普通链表,可以实现两端访问,但是由于非连续空间需要指针,所以内存占用较高、内存碎片也比较多

  • 如果采用ZipList压缩链表,可以实现两端访问并且内存占用较低,但是存储的上限也比较低

  • 因此采用QuickList即LinkedList+ZipList的方式,LinkedList的底层节点为一个个的ZipList,既可以实现双端访问,而且内存占用较低,同时包含多个ZIpList存储上限也比较高

3 set

  • set是redis的集合,不保证有序性、但能够保证元素唯一并能够求差集、交集、并集的特性,并且要求查询效率要高

  • 当存储的所有数据都是整数,并且元素的个数不超过set-max-intset-entries的时候,set就会采用INT编码,以节省内存

    image-20230813085519253
  • 当插入一个字符串或者元素个数过多的时候,set就会转化编码为HASHTABLE,使用Hash Table的key来存储元素,value统一设置为空

    image-20230813085604234
1 为什么redis的set选择哈希表作为存储结构
  • 针对set集合不保证有序性、但能够保证元素唯一并能够求差集、交集、并集的特性,并且要求查询效率要高

  • 如果采用跳表,跳表需要根据score得分进行排序和快速查找,不满足set集合无序的特点,浪费性能

  • 因此采用Hash Table的编码,使用Hash Table的key来存储元素,value统一设置为空

4 Zset

  • Zset也就是SortedSet,每个元素都需要保存一个score值和一个member值,member必须唯一,可以根据score值进行排序,也可以根据member查询score

  • Zset底层编码可以采用ZipList或者HashTable+SkipList组合的方式

  • 当元素个数不多的时候,HashTable+SkipList的组合发挥不出性能优势但是内存占用较多,因此采用ZipList编码:(个数的界限是:元素数量小于zset_max_ziplist_sntries,默认128且每个元素大小小于zset_max_ziplist_value,默认64字节)

    image-20230813092742846
    • 由于ZipList本身既没有键值对,也没有排序的功能,因此需要通过编码实现:
      • ZipLIst是连续的内存,因此可以让element和score占用两个连续的entry实现键值对的存储
      • 通过编码实现排序,每次插入的时候score越小就放到队首,越大就放到队尾
      • 查询也是通过遍历的方式
      • 因为存储元素数量很少,因此时间消耗不会太多但是内存占用远小于HashTable+SkipList的组合
  • 而当元素个数很多的时候,则采用HashTable+SkipList的组合:

    • HashTable可以存储键值对,并且能够保证key唯一、实现通过key快速查找value(score),而SkipList能够同时存储element和score(key、value对应element和score),并实现根据score的排序和范围查询
    • 而在更新的时候,只需要先通过查询HashTable是否存在key,然后依次更新HashTable和SkipList即可
    image-20230813092027610
1 Zset底层结构选取分析
  • 为了满足Zset每个元素都需要保存一个score值和一个member值,member必须唯一,可以根据score值进行排序,也可以根据member查询score的特性

  • 底层的数据结构中,HashTable能够实现键值对的存储,并且能够保证key唯一、实现通过key快速查找value(score),但是是无序的,不能够对score进行排序

  • SkipList则可以根据score进行排序和范围查询,但是本身不能保证key唯一

  • 因此采用HashTable+SkipList的组合

5 Hash

  • Hash的底层编码和Zset类似,只是去掉了用于score排序的SkipList,采用的是ZipList或者HashTable编码

  • 当数据量较小的时候,采用ZipList编码节省内存,ZipList中两个entry分别保存field和value

    数据量大小的判断是:

    ① 元素数量超过hash_max_ziplist-entries,默认512

    ② 元素大小超过hash_max_ziplist-value,默认64字节

    image-20230813094624903

  • 当数据量较大的时候,Hash就转化为了HashTable编码,也就是Dict

    image-20230813094805042

标签:编码,存储,score,数据类型,元素,Redis,五种,HashTable,内存
From: https://www.cnblogs.com/tod4/p/17626194.html

相关文章

  • 第四章 数据类型
    第四章数据类型由数据构成的一个矩形数组称为数据集,行称为观测,列称为变量查看R中所有内置的数据集data(package=.packages(all.available=TRUE))查看指定包中的数据集data(package=“packagename”)查看某个数据集的信息Help函数or?4.1向量向量是数值的有序集,......
  • Java里的数据类型有哪些?
    Java的数据类型主要分为两大类:内置数据类型(基本数据类型):整数类型:byte:8位有符号整数,范围从-128到127。short:16位有符号整数,范围从-32768到32767。int:32位有符号整数,范围从-2,147,483,648到2,147,483,647。long:64位有符号整数,范围从-9,223,372,036,854,775,808到9,223,37......
  • 学习go语言编程之数据类型
    数据类型概述Golang语言内置了如下基础数据类型:布尔类型:bool整型:int8,unit8,int16,uint16,int32,uint32,int64,uint64,int,uint,uintptr浮点类型:float32,float64复数类型:complex64,complex128字符串:string字符类型:rune错误类型:error同时,Golang还支持如下复合类型:指针:pointer数组......
  • Redis主从、哨兵和集群环境搭建
    一、Redis单机安装(1)安装依赖的C语言yuminstall-ygcc-c++automakeautoconflibtoolmaketcl(2)上传安装包并解压cd/usr/local/tmptarzxfredis-5.0.5.tar.gz(3)编译并安装cd/usr/local/tmp/redis-5.0.5/#编译make#安装makeinstallPREFIX=/usr/local/redis(4)开启守护......
  • Redis:高效数据存储与缓存的魔法
    在现代的应用开发中,数据的高效存储和快速访问至关重要。而Redis(RemoteDictionaryServer)正是一款闪电般快速的开源内存数据库,被广泛用于缓存、数据存储、实时分析和排行榜等场景。本文将探讨Redis的基本特性、常见应用场景以及一些最佳实践。1.Redis的核心特性内存存储:Redis将数......
  • redis
    RedisRediswindows安装下载地址:https://github.com/MicrosoftArchive/redis/releases执行redis-cli.exe程序,执行命令setname“my”,返回ok表示成功   Cmd执行上面操作D:\software\Redis>redis-cli.exe-h127.0.0.1-p6379停止服务redis-server.exe--service-sto......
  • Redis启用认证
    要在Redis中启用认证,您需要在Redis配置文件中设置requirepass指令。以下是步骤:找到Redis配置文件。这通常是redis.conf,可能位于/etc/redis/或/etc/目录中,或者在您安装Redis的目录中。打开配置文件并找到requirepass指令。如果没有找到,您可以在文件的任何位置添加它。设置requi......
  • 【后端面经-数据库】Redis详解——Redis基本概念和特点
    目录1.Redis基本概念2.Redis特点2.1优点2.2缺点3.Redis的应用场景面试模拟参考资料声明:Redis的相关知识是面试的一大热门知识点,同时也是一个庞大的体系,所涉及的知识点非常多,如果用一篇文章罗列,往往会陷入知识海洋中无法感知其全貌,因此,这段时间我会试着拆分Redis的相关章节,辅......
  • 【后端面经-数据库】Redis详解——Redis基本概念和特点
    (【后端面经-数据库】Redis详解——Redis基本概念和特点)声明:Redis的相关知识是面试的一大热门知识点,同时也是一个庞大的体系,所涉及的知识点非常多,如果用一篇文章罗列,往往会陷入知识海洋中无法感知其全貌,因此,这段时间我会试着拆分Redis的相关章节,辅以思维导图的形式介绍Redis的相......
  • redis客户端
    QuickRedis连接查询RedisInsight参考连接执行命令RedisClient下载地址解压双击exe文件右键Redisservers->Addserver不用填写密码,如果填写密码会报错查看AnotherRedisDeskTopManage下载地址连接查看......