《Redis - 基础数据结构 - 字典》

一:概述

  - Redis 源码版本为3.0.0.

  - 字典在 Redis 中应用广泛,数据库/哈希表一种方式 底层使用字典实现。

二:字典的基础结构

  - 概述

    - Redis 字典使用哈希表作为底层实现。

    - 一个哈希表中会有多个哈希节点,而每个哈希节点保存了一个键值对。

  - 基本结构

    - 

  - 哈希表节点(dict.h/dictEntry)

    - dictEntry(哈希表节点) 保存了具体的键值对

    - next 用于解决hash冲突

    - 

  - 哈希表(dict.h/dictht)

    - 用于维护整理哈希表节点。

     - 

  - 字典(dict.h/dict)

    - 整个字典的基础外围结构。

    - ht 是一个包含两个dictht 的哈希表。一般情况下,只使用dictht[0],但是在 rehash 中,会使用 dictht[1].

    - 

   

 三:键冲突解决

  - 当发生键冲突时候,会在 dictEntry(哈希表节点) next 构成单向链表,解决键冲突。

  - 为了速度考虑,新加入的键总是在链表头位置。

  - 

四:rehash(重新散列)

  - 原因

    - 随着哈希表的不断进行,哈希表的键值会改变。

    - 为了让哈希表维持在一个合适范围,需要对哈希表大小进行相应的扩展或收缩

  - 原理

    - 分配 ht[1] 空间

      - 如果是扩展操作,分配空间为 ht[0].used * 2 (必须是 2 的 n 次方)

      - 如果是收缩操作,收缩空间为 ht[0].used (必须是 2 的 n 次方)

    - 将 ht[1]  的键值放入  ht[0]  中,同时释放  ht[1] 。

    - 将 ht[1] 置为 ht[0],rehash 完成。

  - 缺点

    - 在 rehash 中,字典表在转移过程中(键值过多时候),导致不可用。

五:渐进式 rehash

  - 概述

    - 解决了直接 rehash 中键值过多导致的字典不可用问题

  - 原理

    - ht[1] 哈希表分配空间,使得字典同时存在 ht[0], ht[1] 两个哈希表。

    - 在字典中维持一个变量 rehashindex, 当 对该字典进行增删改查时,操作 ht[0] 并转移到 ht[1] 中,并 rehashindex + 1

    - 直到所有  ht[0] 中元素都转移到  ht[1],释放 ht[0]

  - 问题

    在 ht[0] 和 ht[1] 同时存在时候,查找键值会先去 ht[0] 再去 ht[1] 找。

六:字典表扩展收缩的条件

  - 负载因子 = ht[0].used(已保存节点数量) / ht[0].size(哈希表大小)

  - 服务器没有进行RDB操作,并负载因子 >= 1

  - 服务器进行RDB操作,并负载因子 >= 5

  - 负载因子 <= 0.1, 收缩操作 

猜你喜欢

转载自www.cnblogs.com/25-lH/p/12639879.html