|NO.Z.00059|——————————|BigDataEnd|——|Hadoop&Redis.V04|——|Redis.v04|RedisDB结构.v04|结构7种type.v02|

一、字典(重点+难点)
### --- 字典(重点+难点)

~~~     字典dict又称散列表(hash),是用来存储键值对的一种数据结构。
~~~     Redis整个数据库是用字典来存储的。(K-V结构)
~~~     对Redis进行CURD操作其实就是对字典中的数据进行CURD操作。
### --- 数组

~~~     数组:用来存储数据的容器,
~~~     采用头指针+偏移量的方式能够以O(1)的时间复杂度定位到数据所在的内存地址。
~~~     Redis 海量存储 快
### --- Hash函数

~~~     Hash(散列),作用是把任意长度的输入通过散列算法转换成固定类型、固定长度的散列值。
~~~     hash函数可以把Redis里的key:包括字符串、整数、浮点数统一转换成整数。
~~~     key=100.1 String “100.1” 5位长度的字符串
~~~     Redis-cli :times 33
~~~     Redis-Server : siphash
~~~     数组下标=hash(key)%数组容量(hash值%数组容量得到的余数)
### --- Hash冲突

~~~     不同的key经过计算后出现数组下标一致,称为Hash冲突。
~~~     采用单链表在相同的下标位置处存储原始key和value
~~~     当根据key找Value时,找到数组下标,遍历单链表可以找出key相同的value

### --- Redis字典的实现

~~~     Redis字典实现包括:字典(dict)、Hash表(dictht)、Hash表节点(dictEntry)。
### --- Hash表

typedef struct dictht {
    dictEntry **table;         # 哈希表数组
    unsigned long size;        # 哈希表数组的大小
    unsigned long sizemask;    # 用于映射位置的掩码,值永远等于(size-1)
    unsigned long used;        # 哈希表已有节点的数量,包含next单链表数据
} dictht;
~~~     # hash表的数组初始容量为4,
~~~     随着k-v存储量的增加需要对hash表数组进行扩容,新扩容量为当前量的一倍,即4,8,16,32
~~~     # 索引值=Hash值&掩码值(Hash值与Hash表容量取余)
### --- Hash表节点

typedef struct dictEntry {
    void *key;                      # 键
    union {                         # 值v的类型可以是以下4种类型
        void *val;
        uint64_t u64;
        int64_t s64;
        double d;
    } v;
    struct dictEntry *next;         # 指向下一个哈希表节点,形成单向链表 解决hash冲突
} dictEntry;
~~~     # key字段存储的是键值对中的键
~~~     v字段是个联合体,存储的是键值对中的值。
~~~     next指向下一个哈希表节点,用于解决hash冲突
### --- dict字典

typedef struct dict {
    dictType *type;               # 该字典对应的特定操作函数
    void *privdata;               # 上述类型函数对应的可选参数
    dictht ht[2];                 # 两张哈希表,存储键值对数据,ht[0]为原生哈希表,
                                  #  ht[1]为 rehash 哈希表 */
    long rehashidx;               # rehash标识 当等于-1时表示没有在rehash,
                                  # 否则表示正在进行rehash操作,存储的值表示
    hash# ht[0]的rehash进行到哪个索引值
    (数组下标)*/
    int iterators;                # 当前运行的迭代器数量
} dict;
### --- type字段,指向dictType结构体,里边包括了对该字典操作的函数指针

typedef struct dictType {
    // 计算哈希值的函数
    unsigned int (*hashFunction)(const void *key);
    // 复制键的函数
    void *(*keyDup)(void *privdata, const void *key);
    // 复制值的函数
    void *(*valDup)(void *privdata, const void *obj);
    // 比较键的函数
    int (*keyCompare)(void *privdata, const void *key1, const void *key2);
    // 销毁键的函数
    void (*keyDestructor)(void *privdata, void *key);
    // 销毁值的函数
    void (*valDestructor)(void *privdata, void *obj);
    
} dictType;
### --- Redis字典除了主数据库的K-V数据存储以外,

~~~     还可以用于:散列表对象、哨兵模式中的主从节点管理等在不同的应用中,
~~~     字典的形态都可能不同,dictType是为了实现各种形态的字典而抽象出来的操作函数(多态)。
~~~     完整的Redis字典数据结构:

### --- 字典扩容

~~~     字典达到存储上限,需要rehash(扩容)
### --- 扩容流程:

~~~     # 说明:
~~~     初次申请默认容量为4个dictEntry,非初次申请为当前hash表容量的一倍。
~~~     rehashidx=0表示要进行rehash操作。
~~~     新增加的数据在新的hash表h[1]
~~~     修改、删除、查询在老hash表h[0]、新hash表h[1]中(rehash中)
~~~     将老的hash表h[0]的数据重新计算索引值后全部迁移到新的hash表h[1]中,
~~~     这个过程称为rehash
### --- 渐进式rehash

~~~     当数据量巨大时rehash的过程是非常缓慢的,所以需要进行优化。
~~~     服务器忙,则只对一个节点进行rehash
~~~     服务器闲,可批量rehash(100节点)
### --- 应用场景:

~~~     主数据库的K-V数据存储
~~~     散列表对象(hash)
~~~     哨兵模式中的主从节点管理

 
 
 
 
 
 
 
 
 

Walter Savage Landor:strove with none,for none was worth my strife.Nature I loved and, next to Nature, Art:I warm'd both hands before the fire of life.It sinks, and I am ready to depart
                                                                                                                                                   ——W.S.Landor

 

 

posted on   yanqi_vip  阅读(134)  评论(0编辑  收藏  举报

相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· DeepSeek 开源周回顾「GitHub 热点速览」
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

导航

统计

点击右上角即可分享
微信分享提示