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;