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

Redis底层设计与源码分析(一)__底层数据结构逻辑分析

前言 

最近在工作中接触redis,但实际应用不多,可用场景也不是很明确,所以想借机多多学习下redis相关知识,一下内容都是通过自己找资源学习之后归纳总结的知识,若有相关错误点,请指正。

一、redis介绍

1.redis为什么效率很高

1)高速的存储介质,redis内容就是存储在内存条中

 2)优良的底层数据结构

 3)高效的网络IO模型

 

4)高效的线程模型

二、redis的底层数据结构说明

问题一:redis底层得数据结构是怎样得呢?

答:

在redis底层采用的数据结构是HashTasble方式,HashTasble就是一个数组,我们把redis一个键值对数据称为数据对象entry,那么HashTasble存放的是各个entry的索引,那么这个索引值是怎么得出来的呢?它是对entry中的key值进行求hash值(hash函数),再将hash值进行求模得出索引值,公式如下:hash(key) % hashTable.size = 索引值                                                                   得到得这个索引值会指向entry,即存储具体得键值对数据。

问题二:通过hash求值得到得索引会存在经典得hash碰撞问题即不同得输入也可能会得到相同得hash值,那么就会导致不同得key所处得hashtable位置相同。在redis中是如何避免这种问题得呢?

答:

redis中所存储得entry,不仅仅有key、value两个值,还有next,用来存储下一个entry得指向,当遇到hash冲突时候redis就会将值放在已有entry得next中,形成链表结构,链表增加元素有两种方式,其一:可以放在链表头,称为头插法,如下:

 

其二:可以放在链尾,称为尾插法,如下:

 而redis采用得便是头插法,原因是为了更快得访问到元素。

问题三:正因为hash冲突得存在,就会使得链表得元素变多,就会使得元素访问变慢,那么redis是如何避免解决这样的问题呢?

答:

在redis中是这样避免链表中元素过多而导致元素检索变慢得。当元素entry个数大于hashtable.size时,redis就会进行扩容,扩容得倍数是原来得一倍,即原来hashtable.size=11,扩容之后新的hashtable.size=22,那扩容之后有了空间就需要进行元素得迁移,即rehash。

当键值对过多时,一次性移动所有键值对会导致Redis在一段时间内无法对外提供服务,所以redis采用得是渐进式 rehash,redis扩容之后便有两个hashtable,原hashtable成为hashtable[0],长度为11,另一个hashtable称为hashtable[1],长度为22,每次对redis执行增删改查操作时,程序在执行指定操作之外,还会将 hashtable[0] 在 rehashidx 索引上的所有键值对,依据hashtable[1]得大小进行重新计算索引位置,然后rehash 到 hashtable[1],之后将 rehashidx 的值加一;rehashidx初始为0,全部迁移完成之后rehashidx便设为-1,并释放hashtable[0]空间。

特别的,在渐进式 rehash 操作过程中,因为同时存在两个哈希表,所以对redis的删除,查找,更新操作会在两个哈希表上进行。程序会先尝试在 ht[0] 中寻找目标键值对,如果没有找到则会在 ht[1] 再次进行寻找,然后进行具体操作。但是新增操作只会在 ht[1] 上进行,这保证了 ht[0] 中的已经被清空的单向链表不会新增元素。

详细得源码分析看《Redis底层设计与源码分析(二)__底层数据结构源码分析》


http://www.kler.cn/news/16991.html

相关文章:

  • 低代码,一招制敌,解决职场人的的办公难题
  • 【热门框架】Maven中聚合,继承指的是什么?有什么作用?
  • 刚转岗做项目经理,无从下手,怎么办?
  • 【硬件】嵌入式电子设计基础之分析电路
  • 视频转gif如何做?三步教你视频转gif制作
  • ClickHouse的资料
  • JetBrains 公布 WebStorm 2023.2 路线图
  • 软件测试技术(四)白盒测试
  • 五面阿里Java岗,从小公司到阿里的面经总结
  • Docker file镜像
  • C/C++内存泄露检查利器—valgrind
  • Linux - 第11节 - 网络基础(一)
  • Ubuntu 23.04 安装 Jupyter
  • Mysql·分库分表
  • 第三十二章 Unity Mecanim动画系统(上)
  • 业绩稳健增长,公牛集团新老业务如何实现齐头并进?
  • 有趣的地理题
  • 排序算法 - 插入排序
  • 流量挂机赚钱项目Traffmonetizer
  • 19. 资源的调度——Label 与 Selector
  • linux怎么防止手误执行了rm / -rf或者rm /* -rf命令?
  • 汉诺塔问题(解出来了带你看洛丽塔)
  • 网络钓鱼仍然是安全行业的祸害
  • IntelliJ IDEA 2023.1正式发布,Maven项目大提速支持Apache Dubbo
  • 大四毕业生想要找实习程序员工作 ,我总结了三点分享给大家
  • String AOP
  • 【代码随想录】刷题Day14
  • Linux之【多线程】生产者与消费者模型BlockQueue(阻塞队列)
  • Linux安装flutter
  • 基于UDQ的并网单相逆变器控制【同步参考系下单相并网全桥正弦PWM逆变器闭环控制】(Simulink)