redis内部数据结构的数据结构
redis对外的公众的数据结构有五种string
,list
, set
,hash
,zset
编码常量 | 编码所对应的底层数据结构 |
---|---|
REDIS_ENCODING_INT | long 类型的整数 |
REDIS_ENCODING_EMBSTR | embstr 编码的简单动态字符串 |
REDIS_ENCODING_RAW | 简单动态字符串 |
REDIS_ENCODING_HT | 字典 |
REDIS_ENCODING_LINKEDLIST | 双端链表 |
REDIS_ENCODING_ZIPLIST | 压缩列表 |
REDIS_ENCODING_INTSET | 整数集合 |
REDIS_ENCODING_SKIPLIST | 跳跃表和字典 |
-
string 底层数据结构
string字符串对象的编码可以是int、raw或者embstr -
list
list 的数据结构是一个双向链表的+ziplist 组成的quicklist -
set
set的底层就是dict和intset -
hash
hash 的底层就是 dict和ziplist -
sortedset
sortedset的底层就是skiplist和ziplist
dic
底层
/*Hash表一个节点包含Key,Value数据对 */
typedef struct dictEntry {
void *key;
union {
void *val;
uint64_t u64;
int64_t s64;
double d;
} v;
struct dictEntry *next; /* 指向下一个节点, 链接表的方式解决Hash冲突 */
} dictEntry;
/* 存储不同数据类型对应不同操作的回调函数 */
typedef struct dictType {
unsigned int (*hashFunction)(const void *key);
void *(*keyDup)(void *privdata, const void *key);
void *(*valDup)(void *privdata, const void *obj);
int (*keyCompare)(void *privdata, const void *key1, const void *key2);
void (*keyDestructor)(void *privdata, void *key);
void (*valDestructor)(void *privdata, void *obj);
} dictType;
typedef struct dictht {
dictEntry **table; /* dictEntry*数组,Hash表 */
unsigned long size; /* Hash表总大小 */
unsigned long sizemask; /* 计算在table中索引的掩码, 值是size-1 */
unsigned long used; /* Hash表已使用的大小 */
} dictht;
typedef struct dict {
dictType *type;
void *privdata;
dictht ht[2]; /* 两个hash表,rehash时使用*/
long rehashidx; /* rehash的索引, -1表示没有进行rehash */
int iterators; /* */
} dict;
ziplist
typedef struct ziplist{
/*ziplist分配的内存大小*/
uint32_t bytes;
/*达到尾部的偏移量*/
uint32_t tail_offset;
/*存储元素实体个数*/
uint16_t length;
/*存储内容实体元素*/
unsigned char* content[];
/*尾部标识*/
unsigned char end;
}ziplist;
/*元素实体所有信息, 仅仅是描述使用, 内存中并非如此存储*/
typedef struct zlentry {
/*前一个元素长度需要空间和前一个元素长度*/
unsigned int prevrawlensize, prevrawlen;
/*元素长度需要空间和元素长度*/
unsigned int lensize, len;
/*头部长度即prevrawlensize + lensize*/
unsigned int headersize;
/*元素内容编码*/
unsigned char encoding;
/*元素实际内容*/
unsigned char *p;
}zlentry;
skiplist
typedef struct zskiplistNode {
/*成员object对象*/
robj *obj;
/*分数字段依赖此值对skiplist进行排序*/
double score;
/*插入层中指向上一个元素level数组*/
struct zskiplistNode *backward;
struct zskiplistLevel {
/*每层中指向下一个元素指针*/
struct zskiplistNode *forward;
/*距离下一个元素之间元素数量, 即forward指向的元素*/
unsigned int span;
} level[];
} zskiplistNode;
typedef struct zskiplist {
/*跳跃表头节点和尾节点*/
struct zskiplistNode *header, *tail;
/*跳跃表中元素个数*/
unsigned long length;
/*跳跃表当前最大层数*/
int level;
} zskiplist;
intset
typedef struct intset {
/*编码*/
uint32_t encoding;
/*长度*/
uint32_t length;
/*集合内容,按升序排列数组*/
int8_t contents[];
} intset;
淘汰策略从大方向分的话就有LRU(最久未使用),LFU(最少使用), TTL(即将过期删除)从这几个划分的小领域淘汰策略具体稍后介绍