redis_5种数据结构及其底层实现原理详解

news2024/10/1 12:13:22

1、 redis中的数据结构

Redis支持五种数据类型:string(字符串),hash(哈希),list(列表),set(无序集合)及zset(有序集合)
在这里插入图片描述
在秒杀项目里,我用过redis的Set和Hash结构:

String:一个 key 对应一个字符串,string是Redis 最基本的数据类型。(字节的abase框架只实现了redis的string数据结构,导致我们如果想要存储复杂的数据结构的时候,只能转成json格式的字符串来存储)
list:一个 key 对应一个字符串列表,底层使用双向链表实现,很多双向链表支持的操作它都支持。
Hash:
在这里插入图片描述

Set:比如一个Set的实例:A = {‘a’, ‘b’, ‘c’},A是集合的key,‘a’, 'b’和‘c’是集合的member。无序、无重复元素。
SortedSet:在set的基础上加上一个分数score,set里面的数据是有序的。

3、 redis数据结构底层实现

string
使用一种叫简单动态字符串(SDS)的数据类型来实现。

/*  
 * 保存字符串对象的结构  
 */  
struct sdshdr {  
    int len;  // buf 中已占用空间的长度  
    int free;  // buf 中剩余可用空间的长度
    char buf[];  // 数据空间  
};

SDS 相比C 字符串的优势:

SDS保存了字符串的长度,而C字符串不保存长度,需要遍历整个数组(找到’\0’为止)才能取到字符串长度。
修改SDS时,检查给定SDS空间是否足够,如果不够会先拓展SDS 的空间,防止缓冲区溢出。C字符串不会检查字符串空间是否足够,调用一些函数时很容易造成缓冲区溢出(比如strcat字符串连接函数)。
SDS预分配空间的机制,可以减少为字符串重新分配空间的次数。

4、 list

使用双向链表来实现。
在这里插入图片描述

5、hash

hash结构里其实是一个字典,有许多的键值对(类似于python的dict类型)。
redis的哈希表是一个dictht结构体:
typedef struct dictht {
dictEntry **table;//哈希表数组
unsigned long size;//哈希表大小
unsigned long sizemask;//哈希表大小掩码,用于计算索引值
unsigned long used;//该哈希表已有节点的数量
}

在这里插入图片描述

哈希表节点的结构体如下:
typeof struct dictEntry{
void *key;//键
union{ //不同键对应的值的类型可能不同,使用union来处理这个问题
void *val;
uint64_tu64;
int64_ts64;
}
struct dictEntry *next;
}

其中解决哈希冲突的方法是拉链法。
为了让哈希表的装载因子维持在一个合理的范围之内,需要对哈希表的大小进行扩展或者收缩,这叫做rehash。字典中总共有两个哈希表dictht结构体,ht[0]用来存储键值对,ht[1]用于rehash时暂存数据,平时它指向的哈希表为空,需要扩展或者收缩ht[0]的哈希表时才为它分配空间。

比如扩展哈希表,就是为ht[1]分配一块大小为ht[0]两倍的空间,然后把ht[0]的数据通过rehash的方式全部迁移到ht[1],最后释放ht[0],使ht[1]成为ht[0],再为ht[1]分配一个空哈希表。收缩哈希表类似。

渐进式rehash:redis并不是专门找时间一次性地进行rehash,而是渐进地进行,rehash期间不影响外部对ht[0]的访问,要求修改字典时要把对应数据同步到ht[1]中,全部数据转移完成时,rehash结束。
————————————————

6、set

set可以用intset或者字典实现。

intset
只有当数据全是整数值,而且数量少于512个时,才使用intset,intset是一个由整数组成的有序集合,可以进行二分查找。
在这里插入图片描述
字典
不满足intset使用条件的情况下都使用字典(拉链法),使用字典时把value设置为null。
在这里插入图片描述

7、 zset

zset中的每个元素包含数据本身和一个对应的分数(score)。
经典例子:一个zset的key是"math",代表数学课的成绩,然后可以往这个key里插入很多数据。输入数据的时候,每次需要输入一个姓名和一个对应的成绩。那么这个姓名就是数据本身,成绩就是它的score。

zset的数据本身不允许重复,但是score允许重复。

zset底层实现原理:
在这里插入图片描述

数据少时,使用ziplist:ziplist占用连续内存,每项元素都是(数据+score)的方式连续存储,按照score从小到大排序。ziplist为了节省内存,每个元素占用的空间可以不同,对于大的数据(long long),就多用一些字节来存储,而对于小的数据(short),就少用一些字节来存储。因此查找的时候需要按顺序遍历。ziplist省内存但是查找效率低。
数据多时,使用字典+跳表:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/437625.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

LED显示屏有色差要怎么处理?

LED显示屏在销售的时候不可避免的会产生尾货。这些尾货由于是不同批次的产品,亮度不可避免的有差异,拼装之后显示效果不佳,这时候就必须使用逐点校正技术。你知道LED显示屏的亮度和对比度是如何调节的吗? 消除差异逐点校正是一项用…

winForm常用控件

一般控件 Label TextBox:文本框 Button RadioButton CheckBox ComboBox:下拉框 CheckedListBox:带复选框的列表项 DateTimePicker:日期时间选择控件 ListBox:列表项 ListView:以五种不同视图显示项的集合 MaskedTextBox:格式化文本框 MonthCalendar:月历 NumberIcUp…

选择Zoho CRM的三大原因

上周,美国IT杂志PCMag发布了关于CRM系统的新评价,Salesforce Sales Cloud Lightning Professional、Zoho CRM、HubSpot CRM、Zendesk、SugarCRM等多个CRM品牌上榜。借此机会,我们来说说Zoho CRM为什么值得推荐? PCMag&#xff0c…

答对这道面试题,直接原地入职:说一下公司常用MySQL分库分表方案

一、数据库瓶颈 不管是IO瓶颈,还是CPU瓶颈,最终都会导致数据库的活跃连接数增加,进而逼近甚至达到数据库可承载活跃连接数的阈值。在业务Service来看就是,可用数据库连接少甚至无连接可用。接下来就可以想象了吧(并发…

XML概述和编写文件

XML概述 XML是一种可扩展的标记语言 标记语言&#xff1a;通过标签来描述数据的一门语言&#xff08;标签有时我们也将其称之为元素&#xff09; 可扩展&#xff1a;标签的名字是可以自己定义的 语法规则示例代码是由一对尖括号和一组合法标识符组成<student>在xml标…

CDN在流媒体的如何内容交付

流媒体是当今最大的趋势之一&#xff0c;这是一种全新的内容消费方式&#xff0c;涉及特定的技术和挑战&#xff0c;视频是目前互联网上要求最多的内容格式&#xff0c;使用CDN分发视频需要与分发其他内容不同。 视频作为内容的本质是不同的&#xff0c;因为用户通常希望立即观…

机器学习入门实例-MNIST手写数据集-二分分类效果评估

接上文的Binary Classifier&#xff0c;将数据分成“是2”和“非2”两类。 Performance Measures 分类效果评价方法 Accuracy&#xff08;准确性&#xff09; y_train_2 (y_train 2) ... from sklearn.linear_model import SGDClassifier sgd_clf SGDClassifier(random_s…

连锁店销售管理系统有哪些功能?应该如何选购?

不管是直营还是加盟&#xff0c;想要实现门店的精细化管理&#xff0c;把不同门店的业绩做好&#xff0c;离不开连锁店销售管理系统的支持。 一款真正能够为连锁店经营带来帮助的连锁店销售管理系统应该具备哪些基本功能&#xff0c;以及选择连锁店销售管理系统时有哪些常见的问…

【科研工具】Zotero实现自动翻译

科研党基本都用过Zotero吧&#xff0c;方便文件管理和做笔记。我常使用的一款插件&#xff0c;可以实现paper英文内容的自动翻译为中文&#xff0c;非常简单、好用&#xff0c;现推荐给大家。 目录 一、下载zotero-pdf-translate插件 1.1 登录GitHub 1.2 找到.xpi文件并下载…

java 拼接字符串的方法

1.拼接字符串的方法&#xff0c;先要将字符串转化为数字类型&#xff0c;再根据需要拼接。这样可以避免直接拼接导致的错误。 2.将字符串转化为数字类型&#xff0c;这个就是一个循环。可以使用循环的方法&#xff0c;但是循环次数不宜太多&#xff0c;否则容易出错。 3.可以使…

微信小程序登陆(全流程-前后端)

环境要求 1.注册一个小程序 2.微信开发者工具 3.idea(springboot) 目录 项目准备 用户登陆 前端开发&#xff0c;传递code index.wxss index.js 后端编写&#xff0c;调用微信接口&#xff0c;获取openId 现在用户的所有信息都拿不到&#xff0c;只能用户自己填写 其…

MySQL的停止与启动、与客户端的连接(参见黑马程序员)

1、启动与停止 &#xff08;1&#xff09;Windowsr 输入 services.msc 在其中找MySQL并点鼠标右键&#xff0c;即可设定是停止还是启动 &#xff08;2&#xff09;以管理员身份打开cmd命令 &#xff08;具体步骤&#xff1a;左下角点搜索输入cmd&#xff0c;在出现的选项里…

数字温湿度传感器DHT11

今天我们来说说一个新的模块DHT11——温湿度传感器 顾名思义&#xff0c;通过开发DHT11能够进行温湿度检测&#xff0c;是一个非常实用且有趣的模块&#xff0c;下面我们先对DHT11基本信息做一个了解&#xff0c;然后进行开发。 DHT11的优点&#xff1a; ►相对湿度和温度测…

算法篇——N个数之和大集合(js版)

1.两数之和 给定一个整数数组 nums 和一个整数目标值 target&#xff0c;请你在该数组中找出 和为目标值 target 的那 两个 整数&#xff0c;并返回它们的数组下标。 你可以假设每种输入只会对应一个答案。但是&#xff0c;数组中同一个元素在答案里不能重复出现。 你可以按…

如何招生?一文教你高职院校有效的招生技巧

生源&#xff0c;是每一所高校的生存之本和生命线。 近几年招生宣传工作作为高职院校招生工作中的重要环节之一&#xff0c;具有政策性强&#xff0c;涉及面广&#xff0c;工作量大等特点&#xff0c;直接关系到学校可持续发展问题。 随着新媒体时代的发展&#xff0c;高职院…

炫酷的3DCSS卡片样式

先效果图展示&#xff1a; 再上代码&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Title</title><style>*,*::after,*::before {margin: 0;padding: 0;box-sizing: bord…

【LeetCode】94.二叉树的中序遍历

1.问题 给定一个二叉树的根节点 root &#xff0c;返回 它的 中序 遍历 。 示例 1&#xff1a; 输入&#xff1a;root [1,null,2,3] 输出&#xff1a;[1,3,2] 示例 2&#xff1a; 输入&#xff1a;root [] 输出&#xff1a;[] 示例 3&#xff1a; 输入&#xff1a;root […

Vue3中使用 EventBus 实现兄弟组件传参

前言&#xff1a;EventBus vue3中没有了&#xff0c;EventBus&#xff0c;所以我们要自己写&#xff0c;但是非常简单。 步骤一&#xff1a;创建&#xff08;EventBus 容器&#xff09; 在src目录&#xff0c;创建个bus文件夹&#xff0c;存放 自己建立的 bus.js class Bus…

Springboot 中快速完成文件上传,整合多平台神器

哈喽&#xff0c;大家好~ 又是做好人好事的一天&#xff0c;有个小可爱私下问我有没有好用的springboot文件上传工具&#xff0c;这不巧了嘛&#xff0c;正好我私藏了一个好东西&#xff0c;顺便给小伙伴们也分享一下&#xff0c;demo地址放在文末了。 文件上传在平常不过的一…

1.黑马Springboot基础篇笔记

Springboot基础篇 1.快速上手Springboot 1.基础配置 1.parent 作用&#xff1a;指定jar包版本信息信息&#xff0c;避免依赖版本冲突 2.starter 作用:SpringBoot中常见项目名称&#xff0c;定义了当前项目使用的所有依赖坐标&#xff0c;以达到减少依赖配置的目的使用任意…