Redis采用一种名为简单动态字符串(simple dynamic string,SDS)的数据结构作为默认字符串的表示。数组
而且在Redis中,只有常量采用默认C语言字符串表示,若是一个字符串是可变的就会采用SDS。 那么,首先让咱们看下SDS数据结构(摘自Redis设计与实现一书)安全
struct sdshdr { // 记录buf数组中已使用字节的数量 // 等于SDS所保存字符串的长度 int len; // 记录buf数组中未使用字节的数量 int free; // 字节数组,用于保存字符串 char buf[]; };
如上图,能够看到这个数据结构包含三部分:用于保存数据的字节
数组,已使用子节的长度和未使用的字节的长度,经过这个设计相信有经验的工程师
已经明白了设计者的思路或用意,正是经过未使用空间,SDS实现了空间预分配和惰性空间释放两种优化策略
.数据结构
说说这两种优化策略的大概思想:函数
当一个SDS最初被建立的时候,free=len,也就是建立的长度等于目标字符串长度;如上图,SDS起初长度为5(Redis),若是须要将这个字符串拼接上Cluster,SDS会预分配内存到(5+7)*2的长度,也就是总长度为拼接后的字符串长度乘以2,此时free=len,这就是SDS预分配时,针对修改后的字符串长度小于1MB时采用的策略;假如修改后的长度大于1MB,SDS会预分配1MB的未使用空间优化
在SDS中,若是字符串在修改后长度变小,SDS并不会当即释放暂时不用的内存空间,而仅仅是修改len和free的值,等待未来使用,举个例子,假如第一次修改操做为缩短8个字节,此后一次修改操做为长度增长7字节,那么SDS就能够重复利用这8字节,经过惰性空间释放策略,SDS避免了缩短字符串时所需的内存重分配操做,并为未来可能有的增加操做提供了优化。 与此同时,SDS也提供了相应的API,让咱们能够在有须要时,真正地释放SDS的未使用空间,因此不用担忧惰性空间释放策略会形成内存浪费。设计
*** 二进制安全 ***code
SDS采用字节数组保存原始数据,采用C末位一个字节为\0的表示方法实现与C函数的兼容,正由于采用的是字节数组才达到了二进制安全的效果,并不是关键内存
综上,SDS同C的默认字符串实现相比,主要起到了以上两部分优化效果字符串