这里我先略过了redis字符串的结构问题,这里我们重点是redis作为kv格式hash其中最为重要的数据结构,字典。 这里面有不得不提到查询哈希。
redis的哈希表结构
其中节点查看如下如图 其中结构体中主要是四个字段(dictht) 分别是: table是主要是存储实际数据节点,其中主要是dictEntry的哈希表数组和数据 size,是table 内哈希表数组的大小 sizemask,是哈希表索引数据位置,size-1 主要是为了接下来进行哈希计算结果的&运算 哈希结果&sizemask used,就是已用哈希数组节点
dictEntry* 这是哈希表,主要是存储相应的数组值也就是下图的dictEntry,其中dictEntry存储着相对应的kv值
哈希表要解决相应的算法问题
1.降低碰撞概率和实际dictEntry链长度 2.合理扩容 3.刷新哈希表,或者进行再次计算
哈希表的碰撞处理
其实这些和大部分方案差不多,都是碰撞就通过链表形式向后链接,同时因为dictEntry存储的本身就是一个kv值对,所以增加next指向下一个哈希值相同的dictEntry形成一个链表平并没有添加太多成本。
哈希表碰撞处理
哈希表的哈希算法主要是通过MurmurHash2,同时增加一步结果&sizemask
dict
主要是以下几项 dictType* type 是制定的哈希类型函数 rehash 是座位调整散列值的表示 ht[] 大部分是两个值 一个是存储哈希数据,一个是用来进行rehash使用的
rehash
其中如果哈希存储的kv值过高,就需要对哈希列表就需要对哈希表也就是dictEntry* 进行扩容活着所容大小是 扩容大小=2的n次方>=dictht.used 缩容大小=2的n次方<=dictht.used 同时进行在另一个ht里面进行rehash,然后讲ht和另一个ht进行交换。
rehash 主要是负载因子公式来判断是否需要进行rehash
其中负载因子的公式 load_factor = ht[0].used/ht[0].size 其中如果BGSAVE或者是BGREWRITEAOF这种持久化命令 ,哈希表负载因子是大于等于5 反之则是大于等于1就行。