Redis入门到通关之数据结构解析-Dict

news2024/12/23 3:11:35

文章目录

  • 概述
  • 构成
  • Dict的扩容
  • Dict的rehash
  • 总结


在这里插入图片描述

欢迎来到 请回答1024 的博客

🍓🍓🍓欢迎来到 请回答1024的博客

关于博主: 我是 请回答1024,一个追求数学与计算的边界、时间与空间的平衡,0与1的延伸的后端开发者。

博客特色: 在我的博客中,开设了如下专栏(点击可以进入专栏奥~): Java、MySQL、Redis、Spring、SpringBoot、SpringCloud、RabbitMQ、微服务、分布式 等相关技术专栏。期待与您一起,探索编程世界中的发现和创新之旅。

🍎🍎🍎我的主页 : https://reply1024.blog.csdn.net

敬请期待定期更新、见解和教程!让我们一起踏上这段编码冒险之旅!

数学与计算的边界 时间与空间的平衡 0与1的延伸


概述

我们知道Redis是一个键值型(Key-Value Pair)的数据库,我们可以根据键实现快速的增删改查。而键与值的映射关系正是通过Dict来实现的。

Dict由三部分组成,分别是:哈希表(DictHashTable)、哈希节点(DictEntry)、字典(Dict)

在这里插入图片描述

当我们向Dict添加键值对时,Redis首先根据key计算出hash值(h),然后利用 h & sizemask来计算元素应该存储到数组中的哪个索引位置。

我们存储k1=v1,假设k1的哈希值h =1,则1&3 =1,因此k1=v1要存储到数组角标1位置。

在这里插入图片描述

构成

Dict由三部分组成,分别是:哈希表(DictHashTable)、哈希节点(DictEntry)、字典(Dict)

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述


Dict的扩容

Dict 中的 HashTable 就是数组结合单向链表的实现,当集合中元素较多时,必然导致哈希冲突增多,链表过长,则查询效率会大大降低。

Dict在每次新增键值对时都会检查负载因子(LoadFactor = used/size) ,满足以下两种情况时会触发哈希表扩容:

  • 哈希表的 LoadFactor >= 1,并且服务器没有执行 BGSAVE 或者 BGREWRITEAOF 等后台进程;
  • 哈希表的 LoadFactor > 5 ;

在这里插入图片描述

在这里插入图片描述


Dict的rehash

不管是扩容还是收缩,必定会创建新的哈希表,导致哈希表的size和sizemask变化,而key的查询与sizemask有关。因此必须对哈希表中的每一个key重新计算索引,插入新的哈希表,这个过程称为rehash。过程是这样的:

  • 计算新hash表的realeSize,值取决于当前要做的是扩容还是收缩:

    • 如果是扩容,则新size为第一个大于等于dict.ht[0].used + 1的2^n
    • 如果是收缩,则新size为第一个大于等于dict.ht[0].used的2^n (不得小于4)
  • 按照新的realeSize申请内存空间,创建dictht,并赋值给dict.ht[1]

  • 设置dict.rehashidx = 0,标示开始rehash

  • 将dict.ht[0]中的每一个dictEntry都rehash到dict.ht[1]

  • 将dict.ht[1]赋值给dict.ht[0],给dict.ht[1]初始化为空哈希表,释放原来的dict.ht[0]的内存

  • 将rehashidx赋值为-1,代表rehash结束

  • 在rehash过程中,新增操作,则直接写入ht[1],查询、修改和删除则会在dict.ht[0]和dict.ht[1]依次查找并执行。这样可以确保ht[0]的数据只减不增,随着rehash最终为空

整个过程可以描述成:
在这里插入图片描述


总结

Dict的结构:

  • 类似java的HashTable,底层是数组加链表来解决哈希冲突
  • Dict包含两个哈希表,ht[0]平常用,ht[1]用来rehash

Dict的伸缩:

  • 当LoadFactor大于5或者LoadFactor大于1并且没有子进程任务时,Dict扩容
  • 当LoadFactor小于0.1时,Dict收缩
  • 扩容大小为第一个大于等于used + 1的2^n
  • 收缩大小为第一个大于等于used 的2^n
  • Dict采用渐进式rehash,每次访问Dict时执行一次rehash
  • rehash时ht[0]只减不增,新增操作只在ht[1]执行,其它操作在两个哈希表

在这里插入图片描述


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

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

相关文章

华为机考入门python3--(18)牛客18- 识别有效的IP地址和掩码并进行分类统计

分类:字符串 知识点: 字符串是否由数字组成 my_str.isdigit() 字符串填充 不足8位左侧填充0 my_str.zfill(8) 题目来自【牛客】 import sys def classify_ip(ip_mask): ip_class, is_private_ip, mask_class ignore_ip, 0, valid_mask# 解…

为什么大模型训练需要GPU,以及适合训练大模型的GPU介绍

文章目录 前言 1、为什么大模型训练需要GPU,而非CPU 2、现在都有哪些合适的GPU适合训练,价格如何 前言 今天偶然看到一篇关于介绍GPU的推文,我们在复现代码以及模型训练过程中,GPU的使用是必不可少的,那么大模型训练需…

如何评价微软发布的Phi-3,手机都可以运行的小模型

前几天才刚刚发布了Llama 3,今天微软就出手了,发布了小而精的phi-3 添加图片注释,不超过 140 字(可选) 刚刚发布的Phi-3系列小模型技术报告,引起AI圈热议。 添加图片注释,不超过 140 字&#x…

DHCP和DNS

DHCP和DNS 一、DHCP服务 1.简介 Dynamic Host Configuration Protocol(DHCP动态主机配置协议) 可以能看见下面的IP、子网掩码、默认网关、DNS都是自动获取得到。但是它是怎么自动获取的,别急我给大家来介绍下 2.DHCP原理 介绍前先给大家…

移动端日志采集与分析最佳实践

前言 做为一名移动端开发者,深刻体会日志采集对工程师来说具有重要意义,遇到问题除了 debug 调试就是看日志了,通过看日志可以帮助我们了解应用程序运行状况、优化用户体验、保障数据安全依据,本文将介绍日志采集的重要性、移动端…

接口测试|超详细面试题【附答案】

今天给姐妹们整理了一套超详细的附答案的接口测试面试题,姐妹们快学起来吧~ 接口测试的重要性,相信不用我多说了。接口测试是现在软件测试工程师一个加分项。因为很多朋友一开始做了几年的软件测试都是在做功能测试,做界面UI的测试&#xff…

(二)Go的Mysql、Redis、Cookie、Logger等的文件配置

初始化配置 文章目录 初始化配置一、配置yaml文件二、Go读取配置文件三、初始化日志Logger四、初始化数据库(MySQL或SqlLite)五、初始化缓存(Redis)六、中间件服务(middleware) 一、配置yaml文件 Server:M…

2024.4.24

求圆半径和周长 #include <iostream> using namespace std;struct Cir { private:int r; public:void set_r(int i);void show(); }; void Cir::set_r(int i)//设置半径 {r i; } void Cir::show()//打印周长面积 {double Pi 3.14;double l 2*Pi*r;double s Pi*r*r;c…

【pycharm】调试模式中四个常用按钮介绍

【pycharm】调试模式中四个常用按钮介绍 在 PyCharm 的调试模式中&#xff0c;有四个常用的按钮&#xff0c;它们的功能如下&#xff1a; Step Over (F8)&#xff1a;单步执行&#xff0c;但在遇到函数调用时&#xff0c;不会进入函数内部&#xff0c;而是将整个函数作为一步执…

技术速递|Java on Azure Tooling 3月更新 - Java on Azure 开发工具未来六个月路线图发布

作者&#xff1a;Jialuo Gan - Program Manager, Developer Division At Microsoft 排版&#xff1a;Alan Wang 大家好&#xff0c;欢迎阅读 Java on Azure 工具的三月更新。在本次更新中&#xff0c;我们将分享未来几个月对 Java on Azure 开发工具的投资。此外&#xff0c;我…

基础SQL DCL语句

DCL是数据控制语言&#xff0c;用来管理数据库用户&#xff0c;还有控制用户的访问权限 1.用户的查询 MySQL的用户信息存储在mysql数据库中&#xff0c;查询用户时&#xff0c;我们需要使用这个数据库。 后面&#xff0c;还有很多数据&#xff0c;因为篇幅的问题&#xff0c;就…

码头船只出行及配套货柜码放管理系统-毕设

毕业设计说明书 码头船只出行及配套货柜码放 管理系统 码头船只出行及配套货柜码放管理系统 摘要 伴随着全球化的发展&#xff0c;码头的物流和客运增多&#xff0c;码头业务迎来新的高峰。然而码头业务的增加&#xff0c;导致了人员成本和工作量的增多。为了解决这一基本问题&…

SpringBoot Bean管理(扫描、注册、注册条件)

Bean扫描 一般的扫描包路径 需要使用xml标签或者是ComponentScan(basePackages “xxx.xxx”) ,但是在SpringBoot中不需要。 在springBoot 项目的启动类中有一个注解&#xff1a;SpringBootApplication,这个注解包含以下注解&#xff1a; 但是ComponentScan并没有指明包路径…

consul ui访问安全加固

本文侧重介绍访问ui安全加固部分。 安装配置以及集群搭建请参考官方文档 下载安装 官方下载地址&安装教程 Install | Consul | HashiCorp Developer 修改配置&#xff0c;开启acl 首先自行规划好 server和client机器。 按照下述流程在server 生成 bootstrap token。 修改ac…

【大语言模型LLM】-基础语言模型和指令微调的语言模型

&#x1f525;博客主页&#xff1a;西瓜WiFi &#x1f3a5;系列专栏&#xff1a;《大语言模型》 很多非常有趣的模型&#xff0c;值得收藏&#xff0c;满足大家的收集癖&#xff01; 如果觉得有用&#xff0c;请三连&#x1f44d;⭐❤️&#xff0c;谢谢&#xff01; 长期不…

openEuler 22.03 LTS SP3(华为欧拉)一键安装 Oracle 11GR2 RAC(231017)

前言 Oracle 一键安装脚本&#xff0c;演示 openEuler 22.03 LTS SP3 一键安装 Oracle 11GR2 RAC&#xff08;231017&#xff09;过程&#xff08;全程无需人工干预&#xff09;&#xff1a;&#xff08;脚本包括 ORALCE PSU/OJVM 等补丁自动安装&#xff09; ⭐️ 脚本下载地…

【学习记录】autoware标定相机与激光雷达外参

一、autoware选择 这里踩了好几个坑&#xff0c;首先autoware作为一个无人驾驶知名框架&#xff0c;其内部实际上是有两套标定的东西的&#xff0c;这一点绝大多数博客没有提到。其中最常用的是一个叫标定工具箱的东西&#xff0c;这个ros包已经在1.10往后的版本中被删掉了&am…

独立搭建UI自动化测试框架分享

今天给大家分享一个seleniumtestngmavenant的UI自动化&#xff0c;可以用于功能测试&#xff0c;也可按复杂的业务流程编写测试用例&#xff0c;今天此篇文章不过多讲解如何实现CI/CD&#xff0c;只讲解自己能独立搭建UI框架&#xff0c;如果有其他好的框架也可以联系我&#x…

springboot基于点餐码 二维码在线点餐系统vue.js+java

Maven: 项目管理和构建自动化工具&#xff0c;用于java项目。 java: 广泛使用的编程语言&#xff0c;适用于构建跨平台应用。 Springmvc:从而在使用Spring进行WEB开发时&#xff0c;可以选择使用Spring的Spring MVC框架。 MyBatis: java持久层框架&#xff0c;支持定制化SQL、存…

网络中其他协议

目录 DNS协议 域名简介 ICMP协议 ICMP功能 ICMP协议格式 ping命令 NAT技术 NATP NAT技术的限制 代理服务器 DNS协议 DNS&#xff08;Domain Name System&#xff0c;域名系统&#xff09;协议&#xff0c;是一个用来将域名转化为IP地址的应用层协议。 为什么有这个协…