《Redis的设计与实现》读笔之redis数据结构与对象

本文介绍了Redis中使用的多种数据结构,包括SDS简单动态字符串、双端List链表、字典、跳跃表、整数集合及压缩列表等。探讨了这些数据结构如何支撑Redis的功能特性,如对象回收机制与对象共享机制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1 数据结构

redis基于这些数据结构创建了一个对象系统,这个系统包含字符串对象、列表对象、hash对象、集合对象、有序集合对象。

另外。redis还是用了基于引用计数(java是可达分析)的回收机制,程序不在用时,对象所在内存就会释放。

redis对象还有访问时间记录信息,用于计算键的空转时常,优先删除空转时常大的键。
在这里插入图片描述

1.1. SDS简单动态字符串

大多情况,String使用了SDS而不是传统的c语言的string。因为保存的string也是key, value形式的,一次key底层是一个SDS, value底层也是一个SDS

SDS: 简单字符串。simple dynamic string

SDS里面包含内容:
  1. free: 为未使用的空间分配的字节数,
  2. len:已经分配的字符串的字节数。
  3. buf(字节数组)是char类型的数组。(其实不是保存字符,而是保存一系列的【二进制数据】,以空字符串结尾’\0’。
  • 修改SDS时候,需要查看分配的字节数目是否符合要求,如果不符合要求,需要先扩展空间。
  • SDS按照处理二进制的方式处理buf数组里的数据。

c:使用n+1长度的字符串表示长度为n的字符串。最后一个元素是空字符。

c字符串不能包含空字符,因为结尾就是\0。因此只能包含无空字符的【文本数据】、图片、饮品、视频这种【二进制数据】不可以。SDS按照处理二进制的方式处理buf数组里的数据。

SDS的优点

1 保存了字符串的长度,get length时降低复杂度。

2 安全,缓冲区溢出的杜绝:c语言不记录自身长度, 因此拼接时,可能会溢出。

3 SDS可以实现空间预分配,和惰性空间释放两种优化策略。SDS内部包含了free区域,尽量减少连续修改(增加)字符串导致【重新分配内存】。字符串缩短的时候也会暂时不修改内存,用free记录这些字节,等待将来的使用。

4. c的string不能保存空字符串,因为用空字符串判断结尾。但是redis的SDS可以,因为利用len来判断是否结尾。

5. sds可以保存文本或进制数据,但是c的只能保存文本数据。

1.2. 双端List链表

在redis中的使用情况:

  • 保存较长字符串作为【列表键】
  • 作为客户端输出缓冲区

redis中的链表是双向的,无环,有len属性对链表节点计数。

1.3. 字典

类似于java中的hashmap: 数组存储key, 桶内是链表,每个节点都有一个next指针。

Redis hash 是一个键值(key=>value)对【集合】。hash 特别适合用于存储对象。

在redis中的使用情况:

  • redis数据库底层
  • hash键的底层实现,hash键包含的键值对很多or键值对中的元素比较长。

redis数据库底层使用字典实现的。对数据库的增删改查操作也是基于字典。

rehash干嘛的:在扩展或者缩小容量的时候,rehash重新计算对应的hash值和索引值,

1.4. 跳跃表zskiplist

查找复杂度:平均O(logN),最坏O(n), 效率和平衡树持平,但是实现起来更简单。

zskiplist的结构:
1. header指针
2. tail指针
3. level最大层数
4. length:表中一共多少个node

zskiplistNode结构:
1. level
2. backward 指针,每个表只有一个后退指针,所以每次只能后退一个
3. score:跳表中节点从小到大排列。
4. 成员对象

使用:

  • zset
  • 集群节点中作为内部数据结构

1.5. intset整数集合

集合键的底层实现之一。intset底层实现为数组。每个项在数组中按从小到大排序。数组中无重复项。

又一个length()保存了数组的长度。

1.6. ziplist压缩列表

当一个列表键只有少量列表项,并且每个列表项要么小整数值,要么是长度短的字符串。

组成:一系列特殊编码的连续内存块组成的顺序型结构。

2 对象

在这里插入图片描述

3 对象回收与对象共享

对象回收:【引用计数】

对象共享:借助引用计数实现。

1. 将键的value指向同一个现有的值对象
2. 将共享的值对象的引用计数+1

对象还会记录最后一次被访问的时间,用于计算对象的空转时间

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值