Redis

发布于 2022-03-02  157 次阅读


redis 的支持的五种数据结构

String

字符串,redis 中字符串 最大为512M 常用命令有GET、SET、INCR、MGET、MSET

Redis 中的String 是由SDS(简单动态字符串)实现的,

struct SDS<T> {
	T capacity; // 数组容量 1byte   使用泛型表示的
	T len; // 数组长度   1byte   使用泛型表示的 
	byte flags; // 特殊标识位  1byte
	byte[] content; // 数组内容   字节数组
}

content 存储数据 capacity 是数据的最大容量 len 是当前字符串的实际长度

content

Redis 中并不是String直接使用SDS , 为了尽可能的快 ,redis 对String的存、取, 尽可能做了优化

int 长度小于21的数字会以int方式存储

SDS 分为两种存储方式 embstr和raw 分别对应不同的空间分配方式

redisObject(Redis对象头) 的数据结构如下

struct RedisObject {
	int4 type; // 4bits   不同的对象会有不同的类型  占4位
	int4 encoding; // 4bits   编码方式 4位
	int24 lru; // 24bits   用于记录lru信息  24位
	int32 refcount; // 4bytes   对象的引用计数   当引用计数为0时  对象会被回收  4个字节     
	void *ptr; // 8bytes,64-bit system  指向对象内容的具体存储位置  8个字节
} robj;

所以一个对象头占16个字节(4bit + 4bit + 24bit +4byte + 8byte)的存储空间

一个SDS结构最少为3个字节 所以创建一个SDS 对象 最少占位(16 + 3)个字节

embstr 会将对象头和SDS 分配在一起 分配内存时也是一次分配,因为内存分配器 的分配到单位是2、4、8、16、32、64 所以一个SDS 结构最少分配32byte , 当超过62之后 Redis 会认为这是一个大字符串, 将会使用raw方式分配, sds 中content内容是以字节\0 结尾,所以embstr 类型剩余可使用长度最大为(64 -19 -1)=44 字节,所以在字符创长度超过44时使用raw 的存储方式

raw 方式 对象头和数据内容 在内存中的位置不连续,分配内存是也是分配两次

SDS 扩容和缩容

当字符串小于1M时 扩容会加倍现在的空间,当字符串大于1M时 每次扩容会额外多增加1M的空间(空间预分配)

释放内存时修改len 字段 并不会实际释放内存(惰性空间释放)

届ける言葉を今は育ててる
最后更新于 2022-03-02