引言

书有四部分,第一二部分通用,

第一部分是介绍redis的底层数据结构与对象

第二部分介绍redis的单机下 日志、过期策略等的实现

第三是多机器的redis(哨兵等)

第四部分是redis的独立功能,如发布订阅、lua等

先从第一部分开始

数据结构-字符串

数据结构

给出Xmind!
图片说明
从C语言说起,众所周知,c/c++C语言的标准库没有string类型,

其实C语言使用'\0'终结的字符数组作为string类型,因为C的标准库的字符串操作都是以此设计的。
另外,一些别的库都会实现自己的string,glib有,reids自然也有

redis自己构造了一套sds结构

struct sdshdr{
    //记录已经使用的字符串数量
    int len;
    //记录buf数组中未使用的字节数量
    int free;
    //字节数组,保存字符串
    char buf[];

}

这套结构有5个优点

其一,常数复杂度获取字符串长度——len属性

在C的字符串需要遍历才能得到长度,redis只要获取len就可以知道长度

其二,内存溢出的危险

假设现在有一个字符串“abc”,我对他进行补充,补充为”abcde“,如果没有记录len和free,那么有可能这么一修改,访问到了不改访问的内存,造成内存溢出。

第三,减少字符串修改代码的性能开销

在c的字符串中,我们的修改,其实就是在底层把数据重新分配内存,这可能要用到系统调用,拿开销是很大的。

因此,用sds这种结构,他又自己的空间分配策略和惰性释放策略。

1、空间分配策略

图片说明
2、惰性空间释放

简单说就是修改free和len的值和buf内部结构,len+free的和是不变的

其四,是二进制安全

c的字符串都要指定某种编码,并且除了末尾,其他位置不能包含空字符

以此记录数据,这带来了很大不方便,比如音频、视频压缩文件这样的二进制不能传输。

而redis-sds的buf字段没有这个限制,buf完全不受限制、过滤等,这可以很大程度的保证数据的一致性,就是“写入”和“写出”一致

其五,兼容c的函数

在redis的sds的api中,基于c语言中原来的做了重写,但是也很大程度的保留了很大方法,比如<string.h>这个库 中stract (字符串后面追加)方法被重用了

数据结构-链表

//每个节点 
typedef struct ListNode{
    //qian
    struct listNode *prev;
    //hou
    struct listNode *prev;
    //节点的值 
    void *value;
}
//整个链 
typedef struct list{
    //头指针 
    ListNode *head;
    //尾
    ListNode *tail;
     //长度 
    unsigned long len;
     //复制函数 
    void *(*dup)(void *ptr);
     //释放内存函数 
    void *(*free)(void *ptr);
     //对比函数 
    void *(*match)(void *ptr);
}

这个链有五个特点:

双端、无环、带头尾节点、带长度、

多态:void 可以兼容多种类型