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 字段 并不会实际释放内存(惰性空间释放)
暂无评论内容