《Redis设计与实现》阅读:Redis底层研究之哈希表hashtable

本文涉及的产品
云数据库 Redis 版,社区版 2GB
推荐场景:
搭建游戏排行榜
简介:         字典是一种存储键值对的抽象数据结构,其又被称为符号表(symbol table)、关联数组(associative array)或映射(map)。Redis使用字典存储键值对,而Redis在底层是通过自定义的哈希表来实现字典这一数据结构的。

        字典是一种存储键值对的抽象数据结构,其又被称为符号表(symbol table)、关联数组(associative array)或映射(map)。Redis使用字典存储键值对,而Redis在底层是通过自定义的哈希表来实现字典这一数据结构的。本文,我们将研究Redis中哈希表的实现。


        结构

        一个哈希表包含多个哈希表节点,每个哈希表节点保存了字典中的一个键值对。在Redis中,哈希表用dictht表示,其结构如下:


        其中,

        1、table是一个数组,里面存储的是用dictEntry表示的哈希表节点,每个节点被用来保存一个键值对;

        2、size表示哈希表的大小,即table数组的大小;

        3、sizemask是哈希表大小掩码,其和键的哈希值一起被使用,用来计算键应该存储在table数组的哪个位置上,其大小固定为size - 1;

        4、used表示目前哈希表已有的哈希表节点数量,也就是键值对的数量。


        再来看下哈希表节点dictEntry的实现,如下:


        其中,

        1、key存储键值对中的键;

        2、v存储键值对中的值,它可以是一个指针,也可以是一个uint64_t整数,还可以是一个int64_t整数;

        3、next是指向另外一个哈希表节点dictEntry的指针,用它来解决键冲突(collision)问题,即两个不同的键哈希值一样,需要存储在table中索引位置index也一样,这样,通过链表形式,将两个key存储在table同一个位置上,解决了键冲突问题。


        最后看下Redis中字典dict的实现,如下:


        其中,

        1、type是指向dictType的指针,而每个dictType保存了一簇用于操作特定类型键值对的函数,为用途不同的词典设置不同的类型特定函数,使得Redis中针对不同类型的键值对,可以创建多态字典。

        2、privdata保存了需要传递给类型特定函数的可选参数;

        3、ht是一个包含两个项的数组,存储两个哈希表dictht,ht[0]用于正常的数据读写,而ht[1]用于在满足一定条件的情况下,哈希表为重新调整负载而进行的rehash操作时的数据暂存,rehash过后,ht[2]会赋值给ht[1],其本身也会被清空;

        4、trehashidx用于避免系统性能瓶颈而采取的渐进式rehash时当前正在进行的索引,记录了rehash的进度,当rehash不在进行时,其值为-1。

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore     ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
5月前
|
存储 NoSQL API
【Redis 系列】redis 学习四,set 集合,hash 哈希,zset 有序集合初步认知
【Redis 系列】redis 学习四,set 集合,hash 哈希,zset 有序集合初步认知
|
6月前
|
存储 NoSQL API
【Redis源码】ziplist压缩表(八)
【Redis源码】ziplist压缩表(八)
53 0
|
2月前
|
存储 缓存 NoSQL
Redis性能滑坡:哈希表碰撞的不速之客【redis第二部分】
Redis性能滑坡:哈希表碰撞的不速之客【redis第二部分】
30 0
|
3月前
|
存储 NoSQL Redis
redis7.0源码阅读(三):哈希表扩容、缩容以及rehash
redis7.0源码阅读(三):哈希表扩容、缩容以及rehash
69 0
|
9月前
|
NoSQL 算法 Redis
Redis集群哈希槽数据分片
Redis 集群有16384个哈希槽,每个key通过CRC16校验后对16384取模来决定放置哪个槽. 集群的每个节点负责一部分hash槽。这种结构很容易添加或者删除节点,并且无论是添加删除或者修改某一个节点,都不会造成集群不可用的状态。
164 0
Redis集群哈希槽数据分片
|
4月前
|
存储 NoSQL Redis
Redis | Redis 哈希相关命令
Redis | Redis 哈希相关命令
47 1
|
6月前
|
消息中间件 NoSQL Java
Redis实现延迟队列,我研究了两种方案,发现并不简单
前段时间有个小项目需要使用延迟任务,谈到延迟任务,我脑子第一时间一闪而过的就是使用消息队列来做,比如RabbitMQ的死信队列又或者RocketMQ的延迟队列,但是奈何这是一个小项目,并没有引入MQ,我也不太想因为一个延迟任务就引入MQ,增加系统复杂度,所以这个方案直接就被pass了。
|
9月前
|
存储 NoSQL Redis
零基础手把手带你阅读Redis源代码系列-ZSet底层原理详解(跳表SkipList)
>之前就说了要来西索Redis,现在来辣! >本文的部分内容参考自《小林Coding》,部分地方根据源代码进行剖析。 >Redis源码地址:https://github.com/redis/redis.git
66 0
零基础手把手带你阅读Redis源代码系列-ZSet底层原理详解(跳表SkipList)
|
9月前
|
存储 NoSQL Redis
零基础小白?带你阅读Redis源码,从零开始分析Set整数集合模型
>之前就说了要来西索Redis,现在来辣! > >本文的部分内容参考自《小林Coding》,部分地方根据源代码进行剖析。 > >Redis源码地址:https://github.com/redis/redis.git ### 观其面 **无序、唯一**的键值结合。 > 这个无序,不是指定没有大小顺序或者字典序,而是不按照插入顺序 Set 类型和 List 类型的区别如下: - List 可以存储重复元素,Set 只能存储非重复元素; - List 是按照元素的先后顺序存储元素的,而 Set 则是无序方式存储元素的。 Set的底层数据结构是由哈希表或者证书集合实现的。 - 如果集合中
61 4
零基础小白?带你阅读Redis源码,从零开始分析Set整数集合模型
|
10月前
|
存储 NoSQL 算法
Redis从入门到精通之答疑为什么ZSet使用跳跃表而不是平衡树、哈希表
有同学阅读了Redis从入门到精通章节中的《Redis从入门到精通之底层数据结构跳表 SkipList》向我提问Redis从入门到精通之答疑为什么ZSet使用跳跃表而不是平衡树、哈希表。今天就做一个解答
887 1
Redis从入门到精通之答疑为什么ZSet使用跳跃表而不是平衡树、哈希表

热门文章

最新文章