RedisSDS(简单动态字符串)
Redis没有直接使用C语言传统的字符串表示,而是自己构建了一种名为简单动态字符串(simpledynamicstring,SDS)的抽象类型,并将SDS用作Redis的默认字符串表示。
字符串内部编码
int:8个字节的长整型。embstr:当值小于等于44字节(版本=Redis3.2),使用embstr。raw:大于44(版本=Redis3.2)个字节的字符串。为什么是44字节?
Redis存储的所有值对象在内部定义为redisObject结构体,内部结构如图:
redisObject各字段说明:
type字段:表示当前对象使用的数据类型,Redis主要支持5种数据类型:string、hash、list、set、zset。可以使用type{key}命令查看对象所属类型,type命令返回的是值对象类型,键都是string类型。encoding字段:表示Redis内部编码类型,encoding在Redis内部使用,代表当前对象内部采用哪种数据结构实现。理解Redis内部编码方式对于优化内存非常重要,同一个对象采用不同的编码实现内存占用存在明显差异。lru字段:记录对象最后一次被访问的时间,当配置了maxmemory和maxmemory-policy=volatile-lru或者allkeys-lru时,用于辅助LRU算法删除键数据。可以使用objectidletime{key}命令在不更新lru字段情况下查看当前键的空闲时间。refcount字段:记录当前对象被引用的次数,用于通过引用次数回收内存,当refcount=0时,可以安全回收当前对象空间。使用objectrefcount{key}获取当前对象引用。当对象为整数且范围在[0-]时,Redis可以使用共享对象的方式来节省内存。具体细节见之后8.3.3节“共享对象池”部分。*ptr字段:与对象的数据内容相关,如果是整数,直接存储数据;否则表示指向数据的指针。Redis在3.0之后对值对象是字符串且长度=39(3.2以后44)字节的数据,内部编码为embstr类型,字符串sds和redisObject一起分配,从而只要一次内存操作即可。Redis在3.2+中embstr使用了叫sdshdr8的结构,embstr将redisObject和SDS保存在连续的64字节空间内。在该结构下,总共64个字节,减去redisObject(16字节),再减去SDS的原信息(3字节),最后的实际内容就变成了44字节。
结论
不同版本的redis如果双写情况出现内存占用量不一样多,可能就是由于sds结构变化导致的。
#redis#