Redis数据结构之字符串(sds)
redisObject
定义如下
struct redisObject {unsigned type:4; //数据类型unsigned encoding:4; /*encoding 编码格式,及存储数据使用的数据结构,同一类型的数据,Redis 会根据数据量,占用内存等情况使用不同的编码,最大限度节省内存 */ unsigned lru:LRU_BITS; int refcount; /*refcount 引用计数,为了节省内存,Redis 会在多处引用同一个 redisObject */void *ptr; //指向真正的数据结构
};
Redis 中的数据对象redisObject 是Redis 对内部存储的数据定义的抽象类型
redisObject是负责装载Redis中的所有的键和值,redis 是真正指向存储数据的数据类型,redisObject.refcount、redisObject.lru 等属性用于数据管理(数据共享,数据过期等)
Redis五种数据结构和编码
字符串 -ads
sds 定义
对于不同长度的字符串,Redis 定义了不同的结构体:
typedef char *sds;
/*关键字 __attribute__ ((__packed__) -----取消结构体内的字节对齐以节省内存
*/
struct __attribute__ ((__packed__)) sdshdr5 {unsigned char flags; /* 第三位表sdshdr的类型,高三位只在sdshdr5 中使用,表示len ,所以sdshdr5中没有len 和 alloc */char buf[];
};
struct __attribute__ ((__packed__)) sdshdr8 {uint8_t len;//已经使用的字节长度uint8_t alloc; //已经申请的字节长度unsigned char flags; //char buf[]; //字符串内容,
};
struct __attribute__ ((__packed__)) sdshdr16 {uint16_t len;uint16_t alloc;unsigned char flags;char buf[];
};
struct __attribute__ ((__packed__)) sdshdr32 {uint32_t len; uint32_t alloc; unsigned char flags; char buf[];
};
struct __attribute__ ((__packed__)) sdshdr64 {uint64_t len; uint64_t alloc; unsigned char flags; char buf[];
};#define SDS_TYPE_5 0
#define SDS_TYPE_8 1
#define SDS_TYPE_16 2
#define SDS_TYPE_32 3
#define SDS_TYPE_64 4
sds 编码
sds 有三种编码
OBJ_ENCODING_EMBSTR:
-
长度小于或者等于OBJ_ENCODING_EMBSTR_SIZE_LIMIT(44字节)的字符串
-
在该编码中redisObject、sds结构存放在一块连续内存中
-
OBJ_ENCODING_EMBSTR 编码是Redis 针对短字符串的优化有如下优点:
- 内存申请和释放都只需要调用一次内存操作函数
- redisObject、sdshdr 结构保存在一块连续内存中,减少了内存碎片
OBJ_ENCODING_RAW:
- 长度大于OBJ_ENCODING_EMBSTR_SIZE_LIMIT的字符串
- 在该编码中redisObject、sds结构存放在两个不连续的内存中
OBJ_ENCODING_INT
数值格式,将数值字符串转换成整型,可以大幅度降低数据占用的空间