Redis存储结构描述

1 redis 存储结构

1.1 redis 存储结构大致框架

在这里插入图片描述

1.3 部分的redis源码展示说明

在这里插入图片描述
redis中数据库的结构定义

在这里插入图片描述
16个数据库由一个数据库对象指针管理,在redis-server的时候,dbnum默认值是16

2 redis 存储转换

在这里插入图片描述

此图已经概括了redis中五种数据类型的全部底层数据结构的划分和存储转换

3 redis的底层数据结构描述

3.1 string

3.1.1 int

字符串长度小于等于20 ,并且能够转成整数。
string 数据类型有一个位图的功能,但是存储位图数据用的是raw 或者是embstr,原因是因为 raw 和embstr 是sds动态字符串,能够节约内存。当然int 是4个字节也是可以用作32位的位图,但是其大小固定比较单一。

3.1.2 raw

raw 也是string的底层数据结构,当字符串的长度大于44时,底层使用raw结构,需要分配两次内存空间(分别为 Redis Object 和 SDS 分配空间)。

3.1.3 embstr

当字符串长度小于44时,底层使用
只分配一次内存空间(因为 Redis Object 和 SDS 是连续的)。
在这里插入图片描述

typedef struct redisObject {
    unsigned type:4;
    unsigned encoding:4;
    unsigned lru:LRU_BITS; /* LRU time (relative to global lru_clock) or
                            * LFU data (least significant 8 bits frequency
                            * and most significant 16 bits access time). */
    int refcount;
    void *ptr;
} robj;
struct __attribute__ ((__packed__)) hisdshdr8 {
    uint8_t len; /* used */
    uint8_t alloc; /* excluding the header and null terminator */
    unsigned char flags; /* 3 lsb of type, 5 unused bits */
    char buf[];
};

当字节数小于44时,分配的大小一直都是64个字节
sizeof(struct redisObject) = 16;
sizeof(hisdshdr8) = 3;
还有一个\0 一个字节
64 - sizeof(struct redisObject) - sizeof(hisdshdr8) -sizeof(“\0”) =44;
因此44 作为raw和embstr的分界点。

3.2 list

3.2.1 quicklist 双向链表

这个不做多个解释

3.2.2 ziplist 压缩列表

这个在list只是间接的使用
ziplist压缩列表详情
ziplist存储是连续的内存空间,可以做压缩。当设计计算时,ziplist明显会比双向链表的指针检索慢,因此ziplist是牺牲时间换取空间的结构。list的底层采取的是压缩列表加双向链表的存储结构,quicklist 为了存储更多的数据,会对每个 quicklistNode 节点进行压缩,这样就可以有效的存储更多的消息队列或者文章的数据了。
当实现为双向链表时,节点会有pre和next指针,每一个指针占8个字节。而ziplist的entry中,用previous_entry_length保存上一个entry的长度,当上一个entry长度小于等于263字节时,previous_entry_length只占一个字节;大于263字节时,previous_entry_length占5个字节,并且ziplist存储是连续的内存空间,可以做压缩。当设计计算时,ziplist明显会比双向链表的指针检索慢,因此ziplist是牺牲时间换取空间的结构

列表的典型使用场景有以下两个:

消息队列:列表类型可以使用 rpush 实现先进先出的功能,同时又可以使用 lpop 轻松的弹出(查询并删除)第一个元素,所以列表类型可以用来实现消息队列;
文章列表:对于博客站点来说,当用户和文章都越来越多时,为了加快程序的响应速度,我们可以把用户自己的文章存入到 List 中,因为 List 是有序的结构,所以这样又可以完美的实现分页功能,从而加速了程序的响应速度。

在这里插入图片描述zlbytes:压缩列表字节长度,占 4 字节;
zltail:压缩列表尾元素相对于起始元素地址的偏移量,占 4 字节;
zllen:压缩列表的元素个数;
entryX:压缩列表存储的所有元素,可以是字节数组或者是整数;
zlend:压缩列表的结尾,占 1 字节。

3.3 hash

3.3.1 dict(字典)

typedef struct dict {
    dictEntry **table;
    dictType *type;
    unsigned long size;
    unsigned long sizemask;
    unsigned long used;
    void *privdata;
} dict;

table :hash指针数组
type: 所以dictType通过函数指针的方式,将不同数据类型的操作都封装起来。从面相对象的角度来看,可以把dictType当成dict中各种数据类型相关操作的interface,各个数据类型只需要实现其对应的数据操作就行
size:hash 数组的大小 通常是2的n次方
sizemask:size-1 一般用作&
used:已经存储的数据个数
其中dictEntry就是对dict中每对key-value的封装,除了具体的key-value,其还包含一些其他信息,具体如下:

typedef struct dictEntry {
    void *key;
    union {   // dictEntry在不同用途时存储不同的数据 
        void *val;
        uint64_t u64;
        int64_t s64;
        double d;
    } v;
    struct dictEntry *next; // hash冲突时开链,单链表的next指针 
} dictEntry;

3.3.2 压缩列表

上面已经讲过。当hash的数据结构中字节数量大于等于512时且字符串长度小于等于64,hash的数据类型才会用压缩列表这个数据结构。

3.4 set

3.4.1 insert 整形数组

元素都为整数且节点数量小于等于512时用整形数组

3.4.2 dict 字典

元素有一个不为整数 或者节点数量大于512 用dict

3.5 zset

3.5.1 skiplist 跳表(后期会专门出一篇博客介绍跳表结构)

节点数量大于128 或者字符串长度大于一64

3.5.2 ziplist

节点数量小于128且字符串长度小于64

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值