redis数据类型概述
Redis数据库由键值对组成,每个键值对都是由对象组成的,键为字符串对象,值可以为字符串对象、list列表对象,哈希对象hash、集合对象set、有序集合sorted set。
redis-SDS
sds-概述
Redis没有使用C语言传统的字符串表示,而是自己构建了一种简单动态字符串,作为redis的默认字符串表示。Redis中,c字符串只会作为字符串字面量(用在一些无需对值进行改变的地方)。其他时候会使用SDS来表示字符串值。例如set msg ”aa“将会创建键值对,键为msg字符串的SDS,值为aa字符串的SDS。例如rpush fruits ”apple“ ”banana“将会创建一个键值对对象,键为fruits字符串的SDS,值为三个SDS的列表对象。AOF的缓冲区中也有SDS的应用。
sds-定义
Redis由c实现,sds主要包含三个部分,free未使用空间长度,len长度、buf为char型数组,保存数据,最后一个字符为空字符\0,不计入len。这样设计的好处是可以使用一些c的原生操作方法。
redis底层使用c实现,那么为什么没有使用c字符串而是使用SDS呢?
1.优化了获取字符串长度
C字符串不记录自身的长度信息,所以获取c字符串长度时,程序必须遍历整个字符串,对遇到的每个字符串进行计数,直到遇到字符串结尾的空字符串为止。这个操作复杂度为O(N).
而对于SDS,获取字符串长度为O(1),维护SDS操作的api由其自身进行,无需操作。
2.杜绝缓冲区溢出
由于c字符串不记录自身长度,那么当用户执行修改字符串操作时,忘了给新的变量分配足够的空间。那么就会造成缓冲区溢出。
而对于SDS来说,完全不需要考虑溢出的问题。当执行修改操作时,SDS会先检查SDS空间是否满足修改所需的要求,如果不满足会自动将SDS的空间进行扩展。
3.减少修改字符串时带来的内存重分配次数
C字符串每次修改都需要重分配内存空间来满足新的字符串需要。Redis为了避免这种情况成为性能的瓶颈,因此做了优化。
字符串变长时,空间预分配
当SDS字符串变长时,那么除了要为sds分配修改所需要的空间,那么还会为sds分配额外的未使用空间。当下次增长时,先检查未使用空间是否满足需求,满足则会直接使用未使用空间。分配规则:SDS长度(len的值)小于1M时,程序分配和len属性同样大小的未使用空间;SDS长度大于1M时,分配1M的未使用空间。
通过预分配,SDS将连续增长N次所需的内存重分配次数从必定N次降低为最多N次。
当字符串变短时,惰性空间释放
SDS变短时将会将释放出的空间放到未使用空间中待下次使用。
4.可以保存二进制数据
C语言字符串以空字符判断是否结尾,那么将会不适合存储带空格的数据。
SDS不存在此问题,长度有len属性进行判断。因此sds可以保存任意长度的数据。
5.兼容部分c字符串函数
延续了c字符串以空字符结尾的习惯,那么将会重用一部分<string.h>库中的部分函数,完成重用的目的。
sds与c字符串区别总结
相关面试问题:redis底层使用c实现,那么为什么没有使用c字符串而是使用SDS呢?