在使用中,redis有五种对象:String、Hash、List、Set、Sorted Set
那么他们在底层是怎么实现的呢?最近阅读了《Redis设计与实现》一书,参考此书阅读了Redis源码,现在记录在此。
在redis中有以下几种数据结构:SDS、链表、字典、跳跃表、整数集合、压缩列表,它们在不同的条件下实现了redis的五种对象。
在这一篇中,记录SDS相关内容。源码来自redis-4.0.11。结构示例图参考《Redis设计与实现》一书。
SDS:simple dynamic string ,即,简单动态字符串。
先来看SDS的结构:(在sds.h中定义了几种不同的结构用来存放不同类型的数据,但结构内容是一样的,所以这里看看存放char的结构)
struct __attribute__ ((__packed__)) sdshdr8 {
uint8_t len; /* buf数组中已使用字节的数量,等于sds所保存的字符串的长度 */
uint8_t alloc; /* 除去头指针和空终止符\0之外,buf数组中未使用的字节的数量 */
unsigned char flags; /* 标记类型 */
char buf[]; /* 用来保存char */
};
考虑这一命令 set msg redis ,此时会在redis数据库中创建一个新的K-V键值对,其中键是一个String对象,底层用一个SDS实现;值也是一个String对象,底层也用一个SDS实现。
以存放 msg 为例子:
len=3
alloc=0(在没有分配多余空间的情况下)
buf数组存储为
'm' | 's' | 'g' | '\0' |
SDS遵循C语言中的字符串以空字符串结尾的惯例。但是空字符串的1字节不会记在len属性中。延续这个惯例是为了方便重用一部分C语言的函数库。