redis源码1

2021/7/8 2:06:15

本文主要是介绍redis源码1,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

redis6.0版本

redis的sds类型 redis是C语言实现在C语言中表示字符串是用char数组表示 但是C语言的这个char当做字符串使用会丢失数据 当这个数组中出现了/0这个字符C语言就会认为读取结束后面的字符都不要了 所以redis自己定义了一个数据类型叫sds(simple dynamic string 简单动态的字符串)它就是有一个函数里面定义了当前char数据长度跟可用长度

redis是一个非关系型的键值对数据库 存储数据利用hash槽这种机制实现效率高 存储的数据会放到一个数组中 在存储的时候会对key做一些运算让它放到对应的数组下标中 当然这样会出现hash碰撞 hash碰撞就是不同的key算出了同一个值会放到同一个对应的下标里 比如算出的结果等于2 那么就会放到arr[2]中 我们所说的redis数据类型 在源码中就是一个函数(java中叫类或者叫方法)这个函数中会有变量指向key的内存地址 也会有变量指向value的内存地址 它还有一个变量指向arr[2]之前所存储过的value然后这个新的值把就的值覆盖放到数组中(arr[2]这个位置)这样形成一个链表结构 解决hash碰撞 但是还有问题 如果这个arr[2]后面跟的数据很庞大那么它的hash机制会淡然失色 这时redis会给我们把这个数组重新扩容翻倍的扩容 什么时候扩容 在redis中这个数据也是一个函数 这个函数中有变量存储当前数据中放了多少个数据 当这个arr[2]所跟的数据大于这个数组的长度时就会扩容 存储的样子大概就是 arr[2] = “k1:v1”; 使用java语法看

RedisDb(redis数据库)主体结构

首先说几个函数(java中可以叫做类或者方法反正就是用来定义变量使用变量的东西)不重要的没写注释 C语言中void可以赋值任意类型

typedef struct redisDb { // 表示redis中数据库的函数
dict *dict; // 用来指向数据的变量
dict *expires;
dict *blocking_keys;
dict *ready_keys;
dict *watched_keys;
int id; // 表示当前数据的id
long long avg_ttl;
unsigned long expires_cursor;
list *defrag_later;
} redisDb;

typedef struct dict {
dictType *type;
void *privdata;
dictht ht[2]; // 用来指向存储数据的数组
long rehashidx;
unsigned long iterators;
} dict;

rehash是 当数据很庞大的时候 要扩容 redis会给我们创建一个新数组 然后把旧数组的数据移到新数组中 正常来说它会让redis阻塞住 但是使用rehash机制当我们对
一个hash槽中的数据做操作的时候它会先把这个槽中的数据快速的复制到新数组中 依次类推 查找数据的时候这两个数组都会被查找优先在旧数组中查询 如果没有操作的时候 它也会轮训的把旧数组中的数据移动到新数组中 移动完把旧数组的指针改成新数组的指针 就是上面ht这个变量 ht[1]旧数组 ht[2]新数组 ht[2]在没有发生rehash时是null

*dict; dict的ht dictht
typedef struct dictht {
dictEntry **table; // 用来指向数据
unsigned long size; // 数组大小
unsigned long sizemask;
unsigned long used; // 存储数据个数解决hash碰撞
} dictht;

typedef struct dictEntry {
void key; // 指向一个sds 在redis中所有key都是字符串类型
union { // 指向redis中的某种数据类型比如redisObject这个函数 一般都是
val指向
void *val;
uint64_t u64;
int64_t s64;
double d;
} v;
struct dictEntry *next; // 之前存储在数组中数据的内存地址
} dictEntry;

typedef struct redisObject {
unsigned type:4; // 代表当前数据时什么类型比如string,set,zet等
unsigned encoding:4;
unsigned lru:LRU_BITS;
int refcount;
void *ptr; // 指向redis中val的内存地址
} robj;

redis 3.2 后 对字符串做了相应的优化(sds)

typedef char *sds; // 所表示redis中字符串的函数

struct attribute ((packed)) sdshdr5 { 这个表示可以存2的5次方-1
unsigned char flags; /* 3 lsb of type, and 5 msb of string length /
char buf[];
};
struct attribute ((packed)) sdshdr8 {这个表示可以存2的8次方-1
uint8_t len; /
used /
uint8_t alloc; /
excluding the header and null terminator 可以空间 /
unsigned char flags; /
3 lsb of type, 5 unused bits /
char buf[];
};
struct attribute ((packed)) sdshdr16 {
uint16_t len; /
used /
uint16_t alloc; /
excluding the header and null terminator /
unsigned char flags; /
3 lsb of type, 5 unused bits /
char buf[];
};
struct attribute ((packed)) sdshdr32 {
uint32_t len; /
used /
uint32_t alloc; /
excluding the header and null terminator /
unsigned char flags; /
3 lsb of type, 5 unused bits */
char buf[];
};
struct attribute ((packed)) sdshdr64 {

redisdb主体结构

在这里插入图片描述

sds示意图
在这里插入图片描述



这篇关于redis源码1的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程