1、字符串
redis字符串支持二进制安全、redis中的健都为字符串类型、redis中所有的健和值都为redisObject变量
- SDS
Bash
len:已用字节长度
alloc:已申请字节长度
flag:低三位代表sdshdr类型
buf:字符串内容
- 根据len判断SDS的类型 (SDS_TYPE_5 || SDS_TYPE_8|| SDS_TYPE_16|| SDS_TYPE_32|| SDS_TYPE_64)
- SDSHDR5存放字节长度小于32(2的5次方)
- SDS可以在常数时间内获取字符串的长度,并使用预分配内存机制减少内存拷贝次数。
-
SDS扩容机制
-
1、判断当前长度是否符合要求,由于sdshdr.len记录了字符长度,时间复杂度为O(1)
-
2、预分配比参数要求多的空间,新的长度若小于SDS_MAX_PREALLOC (1024*1024),则新长度扩容2倍,否则+SDS_MAX_PREALLOC
-
3、扩容后重新计算sdshdr类型
-
4、如果还是同一类型,则使用s_realloc函数申请内存;否则由于sds类型已经变动,需要移动整个sds,直接分配新的内存。
-
5、更新alloc属性
-
字符串编码
- OBJ_ENCODING_EMBSTR (长度大于或小于OBJ_ENCODING_EMBSTR_SIZE_LIMIT=44字节 )
- redis针对短字符串的优化,内存申请和释放只需要一次内存操作
- redisObject、sdshdr结构保存在一块连续的内存中,减少内存碎片
- OBJ_ENCODING_RAW (大于OBJ_ENCODING_EMBSTR_SIZE_LIMIT=44字节 )
- redisObject、sdshdr结构保存在不同的内存中
- OBJ_ENCODING_INT
- 将数值字符串转换为整型,降低占用的内存空间
- 如:"123456789012"占用了12字节,在redistribution中转换为long类型,只用8字节。
- 在redis保存字符串时,会尝试将字符串转换为OBJ_ENCODING_INT ,不行则根据长度保存为OBJ_ENCODING_EMBSTR 或OBJ_ENCODING_RAW。
- 将数值字符串转换为整型,降低占用的内存空间
- 这三种编码为的是尽可能地节省内存