码迷,mamicode.com
首页 > 其他好文 > 详细

redis基础结构-DICT

时间:2020-03-14 20:31:01      阅读:54      评论:0      收藏:0      [点我收藏+]

标签:table   src   seconds   结构图   问题   指针   dict   cron   使用   

DICT

Redis字典具dd有以下特点:

  • Redis字典的底层实现为哈希表,
  • 每个字典使用两个哈希表, 一般情况下只使用 0 号哈希表, 只有在 rehash 进行时, 才会同时使用 0 号和 1 号哈希表。
  • 哈希表使用链地址法来解决键冲突的问题。
  • 自动 Rehash 扩展或收缩哈希表。
  • 对哈希表的 rehash 是分多次、渐进式地进行的。

结构定义

技术图片

/*
 * 字典
 *
 * 每个字典使用两个哈希表,用于实现渐进式 rehash
 */
typedef struct dict {

    // 特定于类型的处理函数
    dictType *type;

    // 类型处理函数的私有数据
    void *privdata;

    // 哈希表(2 个)
    dictht ht[2];

    // 记录 rehash 进度的标志,值为 -1 表示 rehash 未进行
    int rehashidx;

    // 当前正在运作的安全迭代器数量
    int iterators;

} dict;

/*
 * 哈希表
 */
typedef struct dictht {

    // 哈希表节点指针数组(俗称桶,bucket)
    dictEntry **table;

    // 指针数组的大小
    unsigned long size;

    // 指针数组的长度掩码,用于计算索引值
    unsigned long sizemask;

    // 哈希表现有的节点数量
    unsigned long used;

} dictht;

/*
 * 哈希表节点
 */
typedef struct dictEntry {

    // 键
    void *key;

    // 值
    union {
        void *val;
        uint64_t u64;
        int64_t s64;
    } v;

    // 链往后继节点
    struct dictEntry *next;

} dictEntry;

dict添加流程

技术图片

rehash

具体流程

  1. 创建一个比 ht[0]->table 更大的 ht[1]->table , size为大于used*2的2的指数, 开始值为4
  2. 将 ht[0]->table 中的所有键值对迁移到 ht[1]->table
  3. 将原有 ht[0] 的数据清空,并将 ht[1] 替换为新的 ht[0]

开始时机

  • 自然 rehash:ratio >= 1 ,且变量 dict_can_resize 为真
  • 强制 rehash:ratio 大于变量 dict_force_resize_ratio
  • 渐进式rehash:
    • 主动方式:databaseCron中调用dictRehashMilliseconds执行一毫秒
    • 被动方式:调用dictAdd,dicFind,dictDelete,dictGetRandomKey时,调用_dictRehashStep,迁移一个非空桶

redis基础结构-DICT

标签:table   src   seconds   结构图   问题   指针   dict   cron   使用   

原文地址:https://www.cnblogs.com/weiweng/p/12493537.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!