Redis实现原理(2)--字典

1、   Dict

2.1 数据结构定义dict.h

// 哈希表结构

typedef struct dictht {

    dictEntry **table; //哈希表数组指针

    unsigned long size;  //哈希表大小

    unsigned long sizemask; //掩码,hash时用到

    unsigned long used; //已有节点的数量

} dictht;

//  哈希表节点结构

typedef struct dictEntry {

    void *key; 

    union {

        void *val;

        uint64_t u64;

        int64_t s64;

    } v;  // 值,可以是指针类型、uint64和int64

    struct dictEntry *next;  //指向下一节点形成一个单链表

} dictEntry;

//字典定义

typedef struct dict {

    dictType *type;

    void *privdata;

    dictht ht[2];

    int rehashidx; // 重分布标示-1标示正在重分布中

    int iterators; // 重分布进度

} dict;

// 字典类型

// 每个dictType保存了一系列用于操作特定字典的函数,不同用途的字典type不同

typedef struct dictType {

       // hash函数

unsigned int (*hashFunction)(const void *key);

// key的复制

void *(*keyDup)(void *privdata, const void *key);

// value的复制

void *(*valDup)(void *privdata, const void *obj);

// key的比较

int (*keyCompare)(void *privdata, const void *key1, const void *key2);

// key的销毁

void (*keyDestructor)(void *privdata, void *key);

// value的销毁

    void (*valDestructor)(void *privdata, void *obj);

} dictType;

2.2 hash

调用type中得hashFunction方法计算key的hash值,redis内部使用的hash算法为Austin Appleby开发的MurmurHash2算法

h = d->type->hashFunction(key)

计算key的索引值,先在ht[0]中查找,如果没有找到并且在rehash的过程中,则继续在ht[1]中找

idx = h & d->ht[table].sizemask

对于哈希冲突的解决,redis采取的拉链法,相同索引值的key会存储在一个单链表中,所以确定了索引值以后还需要在对应的单链表中进行搜索

while(he) {

            if (dictCompareKeys(d, key, he->key))

                return -1;

            he = he->next;

        }

2.3 rehash

为了保证字典的使用效率,redis对字典结构采取了定期rehash的机制,因为rehash是重CPU的操作,为了避免过程中出现对外无响应的情况,这里做了一种增量rehash的优化

rehash的流程如下:

1)   新建一个空得hash表,size为第一个大于等于2n的整数

unsigned long i = DICT_HT_INITIAL_SIZE;

if (size >= LONG_MAX) return LONG_MAX;

while(1) {

    if (i >= size)

       return i;

    i *= 2;

}

2)   将ht[0]中的key重新计算hash和index,索引到ht[1]中,并将ht[0]中相应的索引值置为空

3)   待ht[0]中的数据全部rehash到ht[1]中之后将ht[1]设置为ht[0],并创建一个新的ht[1]

增量rehash是对步骤2进行优化,每次只rehash一个index的key,并且在rehash过程中对读写操作做限制:

1)      读:先查ht[0],如果没有再在ht[1]上查找

2)      写:rehash过程中,新的key只向ht[1]中写,并且会将索引所对应的所有key重新hash到ht[1]中。

最终会在某个时间点ht[0]中所有的key重新hash到ht[1]中。

Redis实现原理(2)--字典

时间: 2024-10-17 15:42:31

Redis实现原理(2)--字典的相关文章

全面剖析Redis Cluster原理和应用

全面剖析Redis Cluster原理和应用 1.Redis Cluster总览 1.1 设计原则和初衷 在官方文档Cluster Spec中,作者详细介绍了Redis集群为什么要设计成现在的样子.最核心的目标有三个: 性能:这是Redis赖以生存的看家本领,增加集群功能后当然不能对性能产生太大影响,所以Redis采取了P2P而非Proxy方式.异步复制.客户端重定向等设计,而牺牲了部分的一致性.使用性. 水平扩展:集群的最重要能力当然是扩展,文档中称可以线性扩展到1000结点. 可用性:在Cl

Redis实现原理(1)--链表

链表是Redis中使用非常广泛的一种数据结构,很多地方如List结构底层就是用链表实现的. 链表的定义在头文件adlist.h 中,很常见的双向链表,结构如下: 1 // 链表节点 2 typedef struct listNode { 3 struct listNode *prev; //指向前一个节点 4 struct listNode *next; //指向后一个节点 5 void *value; //值域 6 } listNode; 7 // 链表遍历迭代指针 8 typedef str

Redis核心原理

Redis系统介绍: Redis的基础介绍与安装使用步骤:https://www.jianshu.com/p/2a23257af57b Redis的基础数据结构与使用:https://www.jianshu.com/p/c95c8450c5b6 Redis核心原理:https://www.jianshu.com/p/4e6b7809e10a Redis 5 之后版本的高可用集群搭建:https://www.jianshu.com/p/8045b92fafb2 Redis 5 版本的高可用集群的水

基于centos 7的Redis群集原理及配置

博文大纲:一.Redis群集原理二.Redis群集架构细节三.redis-cluster选举四.部署Redis群集环境 关于Redis的性能调优参数的说明,可以参考博文:centos 7之Redis数据库详解及参数调优一.Redis群集原理: 1)Redis集群架构: Redis Cluster采用虚拟槽分区,将所有的数据根据算法映射到0~16384整数槽内 Redis Cluster是一个无中心的结构 每个节点都保存数据和整个集群的状态2)集群角色 Master:Master之间分配slots

《【面试突击】— Redis篇》-- Redis哨兵原理及持久化机制

能坚持别人不能坚持的,才能拥有别人未曾拥有的.关注编程大道公众号,让我们一同坚持心中所想,一起成长!! <[面试突击]— Redis篇>-- Redis哨兵原理及持久化机制 在这个系列里,我会整理一些面试题与大家分享,帮助年后和我一样想要在金三银四准备跳槽的同学.我们一起巩固.突击面试官常问的一些面试题,加油!! <[面试突击]— Redis篇>--Redis数据类型?适用于哪些场景? <[面试突击]— Redis篇>--Redis的线程模型了解吗?为啥单线程效率还这么

全面剖析Redis Cluster原理和应用 (转)

1.Redis Cluster总览 1.1 设计原则和初衷 在官方文档Cluster Spec中,作者详细介绍了Redis集群为什么要设计成现在的样子.最核心的目标有三个: 性能:这是Redis赖以生存的看家本领,增加集群功能后当然不能对性能产生太大影响,所以Redis采取了P2P而非Proxy方式.异步复制.客户端重定向等设计,而牺牲了部分的一致性.使用性. 水平扩展:集群的最重要能力当然是扩展,文档中称可以线性扩展到1000结点. 可用性:在Cluster推出之前,可用性要靠Sentinel

redis相关原理及面试官由浅到深必问的15大问题(高级)

1.redis是什么? redis是nosql(也是个巨大的map) 单线程,但是可处理1秒10w的并发(数据都在内存中) 使用java对redis进行操作类似jdbc接口标准对mysql,有各类实现他的实现类,我们常用的是druid 其中对redis,我们通常用Jedis(也为我们提供了连接池JedisPool) 在redis中,key就是byte redis的数据结构(value): String,list,set,orderset,hash 每种数据结构对应不同的命令语句~ 2.redis

万丈高楼平地起:阿里架构师带你吃透不一样的Redis核心原理实战

前言 随着互联网科技的不断发展,我们以前单纯直接操作数据库的方式已经不能满足现有的高性能和高并发的需求了,于是缓存技术应用而生. Redis是互联网技术领域使用最为广泛的存储中间件,它是「Remote DictionaryService」的首字母缩写,也就是「远程字典服务」.Redis 以其超高的性能.完美的文档.简洁易懂的源码和丰富的客户端库支持在开源中间件领域广受好评.国内外很多大型互联网公司都在使用 Redis,比如 Twitter.YouPorn.暴雪娱乐.Github.StackOve

Redis 复制原理及分析

1.测试 见master-slave测试帖 2 原理 第一次.Slave向Master同步的实现是: Slave向Master发出同步请求(发送sync命令),Master先dump出rdb文件,然后将rdb文件全量传输给slave,然后Master把缓存的写命令转发给Slave,初次同步完成.第二次.以及以后的同步实现是:        Master将变量的快照直接实时依次发送给各个Slave.        但不管什么原因导致Slave和Master断开重连都会重复以上两个步骤的过程.