引言
书有四部分,第一二部分通用,
第一部分是介绍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 可以兼容多种类型