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表节点
相关推荐
m0_74823595几秒前
【MySQL】数据库约束和多表查询
数据库·mysql
知识分享小能手29 分钟前
Java学习教程,从入门到精通,JDBC数据库连接语法知识点及案例代码(92)
java·大数据·开发语言·数据库·学习·java开发·java后端开发
传而习乎1 小时前
sqlite3.OperationalError: database is locked python-BaseException错误解决
数据库·sql·sqlite
orangapple2 小时前
使用Emgu.CV将tif保存视频,并用AxWindowsMediaPlayer打开
前端·javascript·数据库
然然阿然然2 小时前
2025.1.16——一、NewsCenter
数据库·sql·学习·web安全·网络安全
牛马程序员‍3 小时前
【云岚到家】-day03-门户缓存方案选择
redis·缓存·redistemplate·springcache
IT邦德3 小时前
Snowflake归来,荣登DB-Engines榜首
数据库
MC何失眠3 小时前
vulnhub靶场【Raven系列】之2 ,对于mysql udf提权的复习
linux·网络·数据库·mysql·web安全·网络安全
API_technology7 小时前
api开发及运用小红书笔记详情api如何获取笔记详情信息
大数据·开发语言·数据库·数据仓库·笔记·爬虫