Redis设计与实现——数据结构与对象

SDS 简单动态字符串

在redis数据库里面,包含字符串值得键值对在底层都是由SDS实现的。

redis >  set msg "hello world"

1)键值对的键是一个字符串对象,对象得底层实现是一个保存着字符串“msg”的SDS。

2)键值对的值,在底层实现也是保存“hello world ”的SDS。

SDS定义:

SDS与C字符串的区别

1 读取字符串长度复杂度从o(n)降低至o(1)

2)杜绝缓冲区溢出

如果内存中存在紧邻的两个字符串s1,s2,这时候需要需要添加s3至s1之后,如果忘记给s3分配足够的内存空间,那么会导致s3覆盖s2的内存地址。

而如果使用SDS,可以完全杜绝缓冲区溢出的可能性,它会先检查SDS空间是否足够,如果不够就会先扩展SDS内存空间,然后执行拼接操作。

3)减少修改字符串时带来的内存重分配次数

【POC】如果每次修改字符串的长度都需要重新分配内存,那么内存重分配的时间就会占用修改字符串的大部分,对性能造成影响。

通过未使用内存free,SDS实现了空间预分配和惰性空间释放两种优化策略。

空间预留分配:

新增字符串后  len < 1MB   free = len ;

新增字符串后  len > 1MB    free = 1MB;

惰性空间释放:

用于字符串缩短操作,缩短SDS保存的字符串时候,不会立即内存重分配,而是使用free属性记录下来,并未将来可能的增长操作提供优化。

二进制安全

SDS使用len属性值而不是使用空字符串来判断字符串是否结束。使得redis不仅可以保存文本数据,还可以保存二进制数据。

总结

链表

 

字典

哈希算法

rehash

渐进式rehash

跳跃表

Redis只在两个地方用到跳跃表,一个是实现有序集合键,另一个是在集群节点中用作内部数据结构,除此之外跳跃表在redis没有其他用途。

level:除表头节点其他节点的最大层数。   每一层带有两个属性:前进指针和跨度。  BW:后退指针。

 

整数集合

 压缩列表

压缩列表(ziplist)是列表键和哈希键的底层实现之一。当一个列表键只包含少量列表项,并且每个列表项要么都是小整数值,要么都是长度比较短的字符串,那么redis就会使用压缩列表来做列表键的底层实现。

       

 对象

redis是基于上面的数据结构创建了一个对象系统,这个系统包含字符串对象,列表对象,哈希对象,集合对象和有序集合对象这五种类型的对象,每种对象都用到至少一种我们前面所介绍的数据结构。

 内存回收:引用计数技术来实现内存回收。

1)在创建一个新对象时,引用计数的值会被初始化1;

2)当对象被一个新程序使用时,它的引用计数值会被增1;

3)当对象不再被一个程序使用时,它的引用计数值会被减1;

4)当对象的引用计数值变为0时,对象所占用的内存会被释放;

对象共享:

1)将数据库键的值指向一个现有的值对象;

2)将被共享的值对象得引用计数增1;

  

原文地址:https://www.cnblogs.com/gaojy/p/7131320.html