Redis学习(1)--string

114 阅读2分钟

本文已参与[新人创作礼]活动,一起开启掘金创作之路。

Redis基础篇--string

string

内部实现: 动态字符串,类似于JAVA的ArrayList。采取预分配的方式,其分配的实际空间 capacity 一般高于实际长度len。当字符串长度小于1M时,扩容都是加倍;当超过1M时,一次只会多扩1M。注意:其最大长度为512MB.

常见命令:

键值对

set key value   #设置key的值为value
get key         #获取key的值
exists key      #key是否存在
del key         #删除key

批处理

mget key1 key2                #批量获取key
mset key1 value1 key2 value2  #批量设置key和value

过期和set命令扩展

expire key time 	  	#time 秒后过期
setex name 5 whoops 	        #5s后过期,等价于set+expire
setnx name whoops		# 如果name不存在就执行set创建

计数 如果一个value是一个整数,还可以对它进行自增操作。自增是有范围的,它的范围在signed long的最大值和最小值之间,超过了这个范围,redis会报错

set age 30 
incr age #执行自增指令

内部实现

struct SDS<T>{
	T	capacity;       /* 数组容量 */
	T	len;            /* 数组长度 */
	byte	flags;          /* 特殊标志位,不用理踩 */
	byte[] content;         /* 数组内容 */
}

Redis对内存做了极致优化,不同长度的字符串使用不同的结构体来表示.其有两种存储形式,长度特别短的时候使用embstr形式,而当长度超过44字节时,使用raw形式存储

借助 debug object key可以获取key的存储信息

redis对象头结构如下:
struct RedisObject {
	int4	type;           /* 4bits */
	int4	encoding;       /* 4bits */
	int24	lru;            /* 24bits */
	int32	refcount;       /* 4bytes */
	void	*ptr;           /* 8bytes,64-bit system */
} robj;

这样一个RedisObject对象头结构需要16字节的存储空间,再看SDS结构体大小

struct SDS<T>{
	int8	capacity;       /* 1byte */
	int8 len;            /* 1byte */
	int8	flags;          /* 1byte */
	byte[] content;         /* 内联数组,长度为capacity */
}

SDS对象头结构的大小至少是3,因此意味着分配一个字符串的最小空间占用为19字节(即16+3)

embstr 将RedisObject对象头结构和SDS对象连续存储一起,使用malloc方法一次分配,而raw存储形式不一样,它需要使用两次malloc方法,两个对象头在内存地址上一般是不连续的,而内存分配器jemalloc,tcmalloc等分配内存大小的单位都是2/4/8/16/32/64字节,为了容纳一个完整的embstr对象,jemalloc最少会分配32字节。

当分配了64字节时,字符串的最大长度为44字节。 计算 66-19-1(字符串以NULL结尾)=44字节