Redis 对象的实现

1、简单动态字符串

简单动态字符串(simple dynamic string, SDS)是 Redis 的默认字符串表示,是一个可修改的字符串值。Redis 只使用C字符串作为字面量,在大多数情况下,Redis使用SDS作为字符串表示。

STRING 的底层实现之一。

在这里插入图片描述

1.1 SDS 的定义

在这里插入图片描述

1.2 SDS 的空间预分配

当SDS需要空间拓展时,程序会预先分配SDS一些额外的空间。即当SDS长度(len 属性) < 1MB时,分配和len属性同样大小的未使用空间,当SDS长度(len 属性) >= 1MB时,分配1MB大小的未使用空间。

1.3 SDS 的惰性空间释放

SDS 字符串缩短时用free记录,不实际释放内存。

1.4 SDS 二进制安全

C语言的字符串不能包含 \0 ,否则会认为是字符串的结束,因为不能用C语言的字符串保存二进制数据。

而SDS是二进制安全的,可以用来保存任何二进制数据比如图片、序列化对象等等,SDS以len属性判断字符串结尾,程序不会对其中的数据做任何限制或过滤,因此也称SDS的buf是字节数组

但SDS也会在保存数据的结尾设置为\0(不占用len和free,buf多分配一字节),这是为了在SDS保存文本数据时可以重用<string.h>的库函数。

在这里插入图片描述

2、链表

列表(LIST) 的底层实现之一。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3、字典

字典是一种保存键值对的抽象数据结构(保存若干键值对)。字典中的每个键都是独一无二的。

Redis 数据库哈希(HASH)集合SET)的底层实现之一。
在这里插入图片描述

3.1 字典的实现

采用拉链法处理冲突,头插法插入。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
重点:
在这里插入图片描述
Redis 的字典 dict 中包含两个哈希表 dictht,这是为了方便实现渐进式 rehash 操作。在扩容时,将其中一个 dictht 上的键值对渐进地 rehash 到另一个 dictht 上面,这期间发生的查找、删除、更新等操作会分别在两个dictht中找,完成rehash之后释放空间并交换两个 dictht 的角色。
在这里插入图片描述

3.2 rehash

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
linux 的写时复制技术

在linux程序中,fork()会产生一个和父进程完全相同的子进程,但子进程在此后多会exec系统调用,出于效率考虑,linux中引入了“写时复制”技术,也就是只有进程空间的各段的内容要发生变化时,才将父进程的内容复制一份给子进程。

在fork之后exec之前两个进程用的是相同的物理空间(内存区),子进程的代码段、数据段、堆栈都是指向父进程的物理空间,也就是说,两者的虚拟空间不同,其对应的物理空间是一个。当父子进程中有更改相应段的行为发生时,再为子进程相应的段分配物理空间。

渐进式 rehash

在这里插入图片描述
在这里插入图片描述

4、跳跃表

有序集合,ZSET 的底层实现之一。跳跃表是基于多指针有序链表实现的,可以看成多个有序链表。

跳跃表查找特定值的时间复杂度为O(logn),他是一种可以代替平衡树的数据结构。

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
与红黑树等平衡树相比,跳跃表具有以下优点:

  • 插入速度非常快速,因为不需要进行旋转等操作来维护平衡性;
  • 更容易实现;
  • 支持无锁操作。
  • 比红黑树更快进行范围查找,因为底层节点相连。
5、整数集合(intset)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

contents 数组中的元素类型会自动升级
在这里插入图片描述
在这里插入图片描述
整数集合不支持降级操作

6、压缩列表(ziplist)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

7、对象
7.1 对象概述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

7.2 字符串对象(STRING)
  • 如果是整数值,并且这个整数可以用long类型表示,则字符串对象的编码设置为int
  • 如果是长度大于32字节字符串值,则编码设置为raw,使用SDS保存。
  • 如果是长度小于等于32字节字符串值,则使用embstr编码方式保存。
浮点数的处理

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

embstr 简介

在这里插入图片描述
在这里插入图片描述

编码的转换

int 编码的字符串对象和embstr编码的字符串对象在条件满足的情况下,会被转换为raw编码的字符串对象。对于int编码的字符串对象来说,如果我们向对象执行了一些命令,使得这个对象保存的不再是整数值,而是一个字符串值,那么字符串对象的编码将从int变成raw。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

7.3 列表对象(LIST)

列表对象使用ziplist或linkedlist保存。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
字符串对象是Redis五种类型的对象中唯一一种会被其他四种类型对象嵌套的对象。

7.4 哈希对象(HASH)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

7.5 集合对象(SET)

在这里插入图片描述
在这里插入图片描述

7.6 有序集合对象(ZSET)

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
其中 skiplist 编码同时使用了字典跳跃表

  • 如果只使用字典,则根据分数查找的复杂度会是O(N) ,范围查找O(NlogN),因为还需要排序。而有跳跃表则变成O(logN)。
  • 如果只使用跳跃表,则根据元素查找分数或判断此元素是否存在的复杂度会是O(N),而有字典只需O(1)。
8、内存回收

在这里插入图片描述

9、对象共享

在这里插入图片描述

在这里插入图片描述

Redis 只对包含整数值的字符串对象进行共享。(因为验证操作时间复杂度是O(1))

10、对象的空转时长 (用于LRU算法)

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值