您的位置:首页 > 数据库 > Redis

Redis 章节学习总结

2017-07-05 23:36 295 查看
第一章节:简单动态字符串(SDS)

SDS结构定义:

struct sdshdr{

int len;//记录SDS保存的字符串长度

int free;//记录数组中未使用的字节数量

char buf[];//保存字符串

}

SDS与C字符串的区别

复杂度

c字符串并不记录自身记录,获取长度时遍历整个字符串。复杂度为O(N),sds有len属性复杂度为O(1)

缓冲区溢出

c字符串不记录字符串长度,进行strcat容易产生缓冲区溢出。而sds的空间分配策略杜绝了缓冲区的溢出。(对sds进行修改时,先进行空间检查,不满足时,API自动扩展空间大小,再执行修改操作)

内存重分配次数

c字符串每次增长或缩短都会进行一次内存重分配。

(内存重分配涉及复杂算法,是一个比较耗时的操作)

sds采用空间预分配与惰性空间释放策略是先分配优化策略

空间预分配:sds的api对sds修改时,不仅对sds分配必须的空间,还会分配额外的未使用空间

未使用空间数量公式;

1.sds的len属性小于1MB ,分配同len属性相同的未使用空间。

2.sds的len属性大于1MB,程序分配1MB未使用空间。

例:strcat(s,"cluster");//set s "redis"
SDS长度修改为13字节,free分配13字节


惰性空间释放

释放用于优化SDS的字符串缩短操作。缩短字符串时,并不立即回收多出来的字节,而是使用free将字节数量记录起来,待后续使用。

字符编码

C字符串只保存文本数据,SDS可以保存文本或者二进制数据。

第二章节:

整数集合是集合键的底层实现之一。集合包含整数值元素,数量不多,且不重复。

结构:

uint32_t encoding;//编码方式,数组存储真正类型以编码为准

uint32_t length;//集合包含元素数量

int8_t contents[];//存储元素,包含数组项,值按大小排列

升级规则:当新元素添加类型长于现保存类型,整数集合需要整体升级。升级步骤:根据新元素类型扩展整个数组空间,并为新元素分配空间。底层数组现有元素做新类型转换,并存储相应位置,同时维护元素有序性。

第三章节:

链表:提供高效节点重排能力,以及顺序访问节点方式,通过增删改查灵活调整链表长度(列表底层实现之一是链表),多个listNode可以通过prev next形成双向链表。

链表结构:

listNode{

listNode * prev;//前置节点

listNode * next;//后置节点

void * value;//节点值

}

链表特性:

双端:每个节点都有prev next 指针获取某个节点及后置节点复杂度位O(1)

无环:表头表尾都以NULL为终点

带表头及表尾指针,获取表头及表尾复杂度O(1)

带链表计数器,获取长度复杂度O(1)

多态:链表可以保存不同类型的值。

第四章节:

字典:一种用于保存键值对的抽象数据结构

哈希表,哈希表节点

哈希算法:根据键值对计算出哈希值和索引值,然后根据索引值,将包含键值对的哈希表节点放到哈希数组指定索引上。

解决哈希冲突:当多个键被分到同一索引上时,redis采用链地址法来解决冲突,每个哈希节点都有一个next指针,可以通过指针构成一个单项链表。

rehash(重新散列):为了将哈希表的负载因子维持在合理范围内,程序需要对哈希表大小进行相应扩展或收缩

渐进式rehash:字典同时保持两个h[0],h[1]哈希表,分多次渐进式的将一个哈希表的键值rehash到新哈希表上,期间查找先h[0],未找到h[1],新增操作只在h[1]。

哈希表扩展伸缩条件:

1.没有执行bgsave或 bgwriteaof,并且哈希表负载因子大于等于1

2.正在执行bgsave或 bgwriteaof,并且哈希表负载因子大于等于5

3.哈希表负载因子小于0.1时,程序开始执行收缩操作。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: