0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

redis hash底层实现原理

科技绿洲 来源:网络整理 作者:网络整理 2023-12-04 16:27 次阅读

Redis是一个开源的内存数据库,使用键值对存储数据。其中,Redis中的数据结构之一就是哈希(Hash),它提供了一种将多个字段(Field)存储在一个键(Key)中的方法。那么Redis的哈希数据结构是如何实现的呢?本文将详细介绍Redis哈希底层的实现原理。

在Redis中,每个哈希都是由一个类似于字典(Dictionary)的结构实现的,其中使用链地址法解决哈希冲突。整个哈希表的结构如下所示:

typedef struct dict {
dictType *type;
void *privdata;
dictht ht[2];
int rehashidx; /* rehashing 进度标识,当进行渐进式rehash时,这个值表示目前操作的(ht[0]或者ht[1])桶的索引位置*/
int iterators; /* number of iterators currently running 哈希表上目前运行的迭代器数量*/
} dict;
typedef struct dictht {
dictEntry **table; /* 哈希表数组,每个元素都是指向dictEntry结构的指针(指针数组) */
unsigned long size; /* 哈希表大小,是桶数,不能大于2^32 */
unsigned long sizemask; /* 哈希表大小掩码,用于计算索引值,等于size-1,位运算提高性能 */
unsigned long used; /* 哈希表已有节点数量 */
} dictht;
typedef struct dictEntry {
void *key;
union {
void *val;
uint64_t u64;
int64_t s64;
double d;
} v;
struct dictEntry *next; /* 链地址法解决冲突 */
} dictEntry;

上述代码中的dict结构表示一个哈希表,其中ht[0]表示当前哈希表,ht[1]表示进行渐进式rehash时的辅助哈希表(当需要对哈希表进行扩容时,会使用辅助哈希表提前申请新的内存)。

dictht结构表示哈希表内部的哈希数组,table是一个指针数组,将哈希桶中的元素以链表的形式进行存储。

对于每个哈希键值对,Redis使用dictEntry结构来表示,其中key是一个指向键的指针,v是一个联合体,可以存储不同类型的值(Redis值对象),例如整型、浮点型、字符串等。

具体来说,Redis哈希底层实现的步骤如下:

  1. 根据键值对的键,通过哈希函数计算出哈希值。
  2. 根据哈希值计算出存储位置(索引)。
  3. 在哈希表中找到对应索引位置的哈希桶(链表),然后遍历整个链表,查找是否有相同键的节点。
  4. 如果找到相同键的节点,根据操作类型进行更新或删除操作。
  5. 如果没有找到相同键的节点,则创建新的节点并将其插入到链表中。

下面是哈希表的插入、查找、删除的具体实现细节:

  1. 插入:首先通过哈希函数将键转换为哈希值,并计算出插入位置。然后,查询该位置对应的哈希桶,遍历链表,查找是否已经存在相同的键。如果存在相同键,则更新对应节点的值。如果不存在相同键,则创建新的节点并将其插入到链表首部。如果链表长度过长(超过一定阈值),则将链表转化为红黑树(时间复杂度由O(n)降低为O(log n))。
  2. 查找:通过哈希函数计算键对应的哈希值,然后在哈希表中查找对应索引的哈希桶。遍历链表,查找是否存在相同键的节点。如果存在,则返回节点的值;如果不存在,则返回空指针。
  3. 删除:通过哈希函数计算键对应的哈希值,然后在哈希表中查找对应索引的哈希桶。遍历链表,查找是否存在相同键的节点。如果存在,则删除该节点,并释放其内存;如果不存在,则不进行任何操作。

需要注意的是,在Redis中,哈希表的扩容和缩容是通过渐进式rehash来实现的。渐进式rehash的过程分为两个阶段,首先,Redis会在扩容时创建一个新的辅助哈希表(ht[1]),然后将原有哈希表(ht[0])中的节点逐个迁移到辅助哈希表中。在这个过程中,Redis会通过rehashidx来标识当前操作的桶的索引位置。当迁移完成后,Redis会停止对ht[0]的操作,并释放其内存。

综上所述,Redis的哈希底层实现主要是基于字典结构和链地址法解决哈希冲突的思想。通过哈希函数计算键对应的哈希值,并在哈希表中查找对应的哈希桶。通过遍历链表或者红黑树,实现插入、查找和删除等操作。此外,Redis还使用渐进式rehash来实现哈希表的扩容和缩容。通过这些实现,Redis的哈希数据结构能够高效地存储和操作大量的键值对数据。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 内存
    +关注

    关注

    8

    文章

    2991

    浏览量

    73840
  • 数据库
    +关注

    关注

    7

    文章

    3754

    浏览量

    64255
  • Hash
    +关注

    关注

    0

    文章

    32

    浏览量

    13180
  • Redis
    +关注

    关注

    0

    文章

    371

    浏览量

    10834
收藏 人收藏

    评论

    相关推荐

    hash表的实现原理

    软件开发中,一个hash表相当于把n个key随机放入到b个bucket中,以实现n个数据在b个单位空间的存储。 我们发现hash表中存在一些有趣现象: hash表中key的分布规律 当
    发表于 09-28 14:31 0次下载
    <b class='flag-5'>hash</b>表的<b class='flag-5'>实现</b>原理

    Redis基本类型和底层实现

    简单介绍了Redis的五种对象类型和它们的底层实现。事实上,Redis的高效性和灵活性正是得益于对于同一个对象类型采取不同的底层结构,并在必
    发表于 11-25 15:11 4465次阅读
    <b class='flag-5'>Redis</b>基本类型和<b class='flag-5'>底层</b><b class='flag-5'>实现</b>

    redis快速入门详解

    本文下详细汇总了有关于redis知识点。redis是一个开源的key-value数据库。它又经常被认为是一个数据结构服务器。因为它的value不仅包括基本的string类型还有list,set ,sorted set和hash
    的头像 发表于 02-09 11:32 3362次阅读

    Redis五种常见对象类型的底层数据结构

    集合(Zset),我们在日常工作中也会经常使用它们。知其然,更要知其所以然,本文将会带你读懂这五种常见对象类型的底层数据结构。 本文主要内容参考自《Redis设计与实现》 1. 对象类型和编码
    的头像 发表于 11-14 09:50 2966次阅读
    <b class='flag-5'>Redis</b>五种常见对象类型的<b class='flag-5'>底层</b>数据结构

    Springboot+redis操作多种实现

    一、Jedis,Redisson,Lettuce三者的区别共同点:都提供了基于Redis操作的Java API,只是封装程度,具体实现稍有不同。 不同点: 1.1、Jedis 是Redis的Java
    的头像 发表于 09-22 10:48 1789次阅读
    Springboot+<b class='flag-5'>redis</b>操作多种<b class='flag-5'>实现</b>

    Redis实现限流的三种方式分享

    当然,限流有许多种实现的方式,Redis具有很强大的功能,我用Redis实践了三种的实现方式,可以较为简单的实现其方式。
    的头像 发表于 02-22 09:52 1025次阅读

    hash算法在FPGA中的实现(1)

    在FPGA的设计中,尤其是在通信领域,经常会遇到hash算法的实现hash算法在FPGA的设计中,它主要包括2个部分,第一个就是如何选择一个好的hash函数,减少碰撞;第二个就是如何
    的头像 发表于 09-07 17:01 1158次阅读
    <b class='flag-5'>hash</b>算法在FPGA中的<b class='flag-5'>实现</b>(1)

    hash算法在FPGA中的实现(2)

    在前面的文章中:hash算法在FPGA中的实现(一)——hash表的组建,记录了关于hash表的构建,这里记录另外一个话题,就是hash链表
    的头像 发表于 09-07 17:02 739次阅读
    <b class='flag-5'>hash</b>算法在FPGA中的<b class='flag-5'>实现</b>(2)

    Redis的数据类型有哪些

    Redis的数据类型有哪些?有五种常用数据类型:String、Hash、Set、List、SortedSet。以及三种特殊的数据类型:Bitmap、HyperLogLog、Geospatial
    的头像 发表于 10-09 10:51 758次阅读

    Redis底层数据类型

    1. 前言 Redis的键值对中的常见数据类型有String (字符串)、List(列表)、Hash(哈希)、Set(集合)、Zset(有序集合)。那么其对应的底层数据结构有SDS(simple
    的头像 发表于 10-09 14:05 358次阅读
    <b class='flag-5'>Redis</b><b class='flag-5'>底层</b>数据类型

    redis的五种数据类型底层数据结构

    Redis是一种内存数据存储系统,支持多种数据结构。这些数据结构不仅可以满足常见的存储需求,还能够通过其底层数据结构提供高效的操作和查询。以下是Redis中常用的五种数据类型及其底层
    的头像 发表于 11-16 11:18 678次阅读

    Redis工具集的实现和使用

    Redis 基本上是互联网公司必备的工具了,Redis的应用场景实在太多了,但是有很多相似的功能如果每个项目都要实现一遍就显得太麻烦了,所以为了方便,我打算开发一个基于 Redis
    的头像 发表于 12-03 17:32 1181次阅读
    <b class='flag-5'>Redis</b>工具集的<b class='flag-5'>实现</b>和使用

    redis集群中的hash一致性算法的理解

    的单节点Redis已经无法满足高并发读写和大容量存储的需求。为了解决这个问题,Redis集群应运而生。 Redis集群通过将数据分散到多个节点上,实现了水平扩展,使得
    的头像 发表于 12-04 10:45 707次阅读

    Java redis锁怎么实现

    在Java中实现Redis锁涉及到以下几个方面:Redis的安装配置、Redis连接池的使用、Redis数据结构的选择、
    的头像 发表于 12-04 10:47 1101次阅读

    redis数据结构的底层实现

    Redis是一种内存键值数据库,常用于缓存、消息队列、实时数据分析等场景。它的高性能得益于其精心设计的数据结构和底层实现。本文将详细介绍Redis常用的数据结构和它们的
    的头像 发表于 12-05 10:14 583次阅读