在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
本笔记参考《Redis设计与实现》 P24~ 37 Redis字典实现哈希表节点结构typedef struct dictEntry { // 键 void *key; // 值 : 可以是一个指针,或者是一个uint64/int64 的整数 union { void *val; uint64_t u64; int64_t s64 } v; // 指向下一个哈希表节点,形成链表 : 该指针可以将多个哈希值相同的键值对连接在一起,以此解决键冲突的问题。 struct dictEntry *next; } dictEntry; 哈希表结构typedef struct dictht { // 哈希表数据 dictEntry **table; // 哈希表集合大小 unsigned long size; // 哈希表大小掩码,用于计算索引值 // 总是等于 size - 1 unsigned long sizemask; // 哈希表已有节点数量 unsigned long used; } dictht; 字典typedef struct dict { // 类型特定函数 dicType *type; // 私有数据 void *privdata; // 哈希表 dictht ht[2]; // rehash 索引 // 当rehash不在进行时, 值为-1 int rehashidx; } dict; type属性和privdata属性针对不同类型的键值对,为多态字典而设置。 哈希算法
hash = dict->type->hashFunction(key);
index = hash & dict->ht[x].sizemask; redis使用的是MurmurHash算法,优点是:输入的键是有规律的时候,算法仍然能给出很好的随机分布性,计算速度也快。 解决hash冲突当有两个或以上的key分配到了hash table数组的同一个index上,称为发生了collision。 rehash随着操作不断执行,哈希表保存的key value对会逐渐增加和减少。哈希表有一个统计参数load factor,即负载因子,公式如下: # 负载因子 = 哈希表已经保存的节点数量 / 哈希表大小 load_factor = ht[0].used / ht[0].size; 为了维持负载因子在一个合理的范围,程序会对哈希表的大小进行相应的扩展或收缩,条件如下: 1、服务器目前没有执行BGSAVE命令或者BGREWRITEAOF命令,并且哈希表的负载因子 >= 1 2、服务器正在执行BGSAVE命令或者BGREWRITEAOF命令,且负载因子 >= 5
渐进式hashrehash的动作并不是一次性集中完成的,而是分多次渐进完成。 需要注意的地方 到此这篇关于Redis字典实现、Hash键冲突以及渐进式rehash的文章就介绍到这了,更多相关Redis 渐进式rehash内容请搜索极客世界以前的文章或继续浏览下面的相关文章希望大家以后多多支持极客世界! |
请发表评论