• 《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, 收缩操作 

  • 相关阅读:
    其实 Linux IO 模型没那么难
    七年三次大重构,聊聊我的重构成长史
    听说 JVM 性能优化很难?今天我小试了一把!
    盘点三年来写过的原创文章
    如何快速实现一个连接池?
    树结构系列(四):MongoDb 使用的到底是 B 树,还是 B+ 树?
    树结构系列(三):B树、B+树
    树结构系列(二):平衡二叉树、AVL树、红黑树
    树结构系列(一):从普通树到二叉查找树
    静态代码分析工具清单
  • 原文地址:https://www.cnblogs.com/25-lH/p/12639879.html
Copyright © 2020-2023  润新知