Redis数据结构底层存储
- 时间:
- 浏览:0
- 来源:跟我学网络
关于redis内部实现,涉及内存内存分配器(jemalloc),简单动态字符串(sds),5种对象类型及内部编码,redisObject。
- dictEntry: 每个键值对都会对应这个结构,存储指向key、value的指针
- key: 并不直接用字符串存储,使用sds结构
- value: 都使用redisObject结构,可以绑定不同类型,如string,set,zset,hash,list
- jemalloc: 所有对象都需要使用分配器分配内存。
redisObject结构
typedef struct redisObject { unsigned type:4; unsigned encoding:4; unsigned lru:REDIS_LRU_BITS; /* lru time (relative to server.lruclock) */ int refcount; void *ptr; } robj;
- type: 对象的类型,如REDIS_STRING,REDIS_REDIS_LIST,REDIS_REDIS_HASH,REDIS_REDIS_SET, REDIS_REDIS_ZSET
- encoding: 对象的内部编码,占4个字节
- lru: 对象最后一次被程序访问的时间。volatile-lru或allkeys—lru中,优先释放空转时间最长的对象。
- refcount: 记录该对象被引用的次数,类型为整型。
- Redis中被多次引用的对象,成为共享对象
- 目前共享对象只支持整形的字符串对象 (CPU和时间的平衡,整形判断相同复杂度O(1),其他类型O(n))
- 目前redis在初始化时,会创建10000个字符串对象,0~9999
- Ptr: 指向具体的对象
SDS和C中string的区别
redis没有使用C中以’\0’结尾的字符串数组,而使用了Simple Dynamic String,简单动态字符串.
struct sdshdr { int len; // buf已使用的长度 int free; // buf未使用的长度 char buf[]; // 字节数组 };
优越性:
- 获取字符串长度
- 杜绝缓冲区溢出,减少修改字符串时带来的内存重分配次数
- 可存取二进制数据。C字符串以空字符串作为字符串结束的标志,而对于一些二进制的文件,内容可能包括空字符串,因此C字符串不能正确存储。而sds会记录数据长度,所以可以避免。