Redis系列之底层数据结构字典Dict

Redis系列之底层数据结构字典Dict

Dict数据结构

Dict是Redis数据结构中使用最为频繁的复合型数据结构,本质上是一个哈希表

查看redis6.0版本的源码,链接:https://github.com/redis/redis/blob/6.0/src/dict.h

哈希表的结构定义:

cpp 复制代码
typedef struct dictht{
    //哈希表数组
    dictEntry **table;
    //哈希表大小
    unsigned long size;
    //哈希表大小掩码,用于计算索引值,总是等于 size-1
    unsigned long sizemask;
    //哈希表已有节点的数量
    unsigned long used;
}dictht

哈希表由数组table组成,table 中每个元素都是指向dictEntry这种数据结构,key用来保存键,val用来保存值,值可以是一个指针,也可以是uint64_t整数,也可以是int64_t整数

cpp 复制代码
typedef struct dictEntry{
     //键
     void *key;
     //值
     union{
          void *val;
          uint64_tu64;
          int64_ts64;
     }v;
 
     //指向下一个哈希表节点,形成链表
     struct dictEntry *next;
}dictEntry

Dict在redis中的应用

在Redis中,Dict数据结构应该是使用最为频繁的复合型数据结构,除了在hash数据的会使用字典外,整个Redis的key和value也组成一个全局字典,Zset集合中存储value和score值的映射关系也是通过字典结构实现的

Redis的key和value映射使用dict

cpp 复制代码
struct RedisDb{
    dict* dict;// all keys key=>value
    dict* expires;
    ...
}

zset中存储value和score值的映射关系,使用dict

cpp 复制代码
struct zset {
    dict *dict; // all values value=>score
    zskiplist *zsl;
}

Dict如何解决hash冲突

dict本质也是一种key、value结构的哈希表,所以就有哈希冲突的问题,如果学过java中hashmap的数据结构,应该知道解决哈希冲突,常见的方法有开放地址法和链地址法。redis中的dict采用的是链地址法,也可以说使用链表来解决hash冲突。redis 中的dict通过next指针,可以将多个哈希值相同的键值对连接起来,用来解决哈希冲突

Dict拓展知识点

  • redis中计算哈希值和索引值的方法
cpp 复制代码
# 使用字典设置的哈希函数计算哈希值
hash = dict->type->hashFunction(key);
# 使用前面计算的哈希值hash和dict的sizemask计算索引值
index = hash & dict->ht[x].sizemask;
  • dict的扩容和收缩,dict保存的键值对太多或者太少时,会触发dictRehash操作,重新散列来对哈希表进行扩容或者收缩。注意dict的rehash操作是渐进式的,因为如果键值对数量过多,要进行rehash操作是很耗时的,所以redis采用渐进式rehash,分多次、渐进式完成rehash操作
  • hash冲突,redis dict哈希冲突的解决方法是采用链地址法,通过*next指针指向下一个具有相同索引值的hash表节点
相关推荐
2401_891409262 分钟前
国外期货高频数据:历史高频分钟回测数据分享
数据库·金融
喻师傅4 分钟前
横扫SQL面试——用户留存率问题
数据库·sql·面试
暗恋 懒羊羊9 分钟前
【MySQL】表的操作
数据库·mysql
意疏33 分钟前
【数据结构篇】算法征途:穿越时间复杂度与空间复杂度的迷雾森林
数据结构
likfishdn36 分钟前
SQL注入零基础学习二MYSQL手工注入
数据库·sql·学习
Databend1 小时前
Databend 产品月报(2025年3月)
数据库
画个逗号给明天"2 小时前
C#从入门到精通(4)
数据库·c#
Chandler242 小时前
Redis:持久化 RDB快照 AOF日志
数据库·redis·缓存
LCY1332 小时前
redis错误分析 forceUnlock的问题说明
数据库·redis·缓存
Cloud_.2 小时前
Spring Boot整合Redis
java·spring boot·redis·后端·缓存