Redis 底层数据结构主要包括:
- 字符串(String)
- 字典(Hash)
- 链表(List)
- 集合(Set)
- 有序集合(Sorted Set,或称为 zset)
这些数据结构在 Redis 中都是基于以下两种底层实现:
- 静态字符串(Simple dynamic string, SDS):一种动态字符串实现,用于存储字符串数据。
- 跳跃表(Skip list):一种复合的数据结构,可以在对数平均时间内执行排序和搜索操作,Redis 的 zset 就是基于此实现。
以下是 Redis 中字符串数据结构的简单实现:
// 静态字符串定义
struct sdshdr {
long len; // 记录buf中已使用的字节数
long free; // 记录buf中未使用的字节数
char buf[]; // 字符串数据存储区
};
// 字符串对象定义
typedef struct redisObject {
unsigned type:4; // 对象类型
unsigned encoding:4; // 对象编码
unsigned lru:LRU_BITS; // 对象最后一次被访问的时间
int refcount; // 对象引用计数
void *ptr; // 指向实际的数据
} robj;
// 创建一个字符串对象
robj *createStringObject(const char *ptr, size_t len) {
// 为sdshdr和字符串数据分配空间
robj *o = zmalloc(sizeof(robj)+sizeof(struct sdshdr)+len+1);
struct sdshdr *sh = (void*)(o+1);
// 初始化robj
o->type = REDIS_STRING;
o->encoding = REDIS_ENCODING_RAW;
o->ptr = sh+1; // ptr指向数据区
o->refcount = 1;
// 初始化sdshdr
sh->len = len;
sh->free = 0;
if (ptr) {
memcpy(sh->buf, ptr, len);
} else {
memset(sh->buf, '', len);
}
sh->buf[len] = '\0';
return o;
}
以上代码仅为示例,实际的 Redis 源码会更加复杂,包含对象共享、内存分配策略等多种优化措施。