redis数据结构,网上资料也很多,redis设计与实现书上讲的也很明白,具体的也可以参考博客专栏,这里只对redis2.8和4.0版本做个简单的对比:
http://blog.csdn.net/column/details/15428.html
(sds,list,dictht,skiplist,intset,ziplist,quicklist)
简单动态字符串(sds),在Redis需要的不止是字符串字面量,而是一个可以被修改的字符串值时,Redis会使用SDS来表示,这里可以先看其定义,在2.8和4.0版本中定义是不一样的,4.0中的版本中有sdshdr5、sdshdr8、sdshdr16、sdshdr32、sdshdr64五种类型,可以在sds.h文件中找到。
redis2.8
struct sdshdr{
int len;// 记录buf数组中已经使用的字节数量
int free;//记录buf中未使用的字节数量
char buf[];//字节数组,用于保存字符串
};
redis4.0
struct __attribute__ ((__packed__)) sdshdr64 {
uint64_t len; //记录buf数组中已经使用的字节数量
uint64_t alloc; //分配的总字节数
unsigned char flags; //用0、1、2、3、4代表类型
char buf[];
};
SDS有以下好处:
1、可以以O(1)获取数组长度。
2、避免缓冲区溢出,因为当SDS需要修改时,会先检查空间是否足够,不够的话会自动扩容,然后修改。
3、减少内存重分配,c中对append或者trim操作会重新分配内存,而sds通过空间预分配和惰性空间释放对其进行了优化。
(空间预分配是在修改SDS之后,对于SDS的长度小于1MB时,程序会分配和当前数组len长度一致的free空间,而当修改的SDS的总长度大于1MB,则会多分配1MB的free空间。惰性空间释放既在对SDS进行截断或者缩短时,不会立即回收多出来的内存,而是将free增加,这样在可以保证避免频繁操作,当日SDS也提供了API可以真正释放内存。)
链表(list )是列表键的底层存储结构之一,定义在adlist.h文件中,链表类型在2.8中用于list的实现,在4.0中list则全部使用quicklist实现。
redis2.8和4.0中一致
typedef struct listNode {
struct listNode *prev;//前置节点
struct listNode *next;//后置节点