Redis设计与实现阅读总结(一)数据结构和对象

article/2025/10/14 3:46:56

Redis设计与实现阅读总结(一)数据结构和对象

最近团队几个人和我聊了下,加上我自己平时的反思,我发现自己问题确实很多

其中一个问题就是,自己学习东西没有系统性,没有总结

这次的博客算是一个总结的开始。

最近由于出实习题,趁着这个机会,自己阅读了《redis设计与实现》这本书

为了解决自己的毛病,准备围绕这个话题写博文,做总结,从细节到总体,围绕这个话题写更多东西

大家可能发现这个部分写的很粗略,因为redis本身设计的就是很简单的,这些数据结构基本没有太多好写的,主要是写了后做一个总结,后面的更为重要的部分会做更多叙述

1. SDS(简单动态字符串)

每个 sds.h/sdshdr 结构表示一个 SDS 值:

struct sdshdr {// 记录 buf 数组中已使用字节的数量// 等于 SDS 所保存字符串的长度int len;// 记录 buf 数组中未使用字节的数量int free;// 字节数组,用于保存字符串char buf[];};

img

为什么不使用c语言简单字符串

原因有如下

  • 获取长度复杂度为O(1)
  • 避免缓冲区溢出

优化策略

redis非常注重性能,于是优化是非常必要的。

减少内存重分配

  1. 空间预分配

内存的分配设计到复杂算法或可能的系统调用,比较耗时

于是,每次再字符串增长操作时,不仅仅会扩容到刚好所需的空间,而是会通过一定策略额外分配空间

  1. 惰性空间释放

字符串的缩短操作,不会进行内存重分配,而是会通过free记录起来,为未来可能存在的增长提供优化

二进制安全

不使用\0辨认结尾,而是通过len

并且在SDS中\0被保留,可以兼容部分c字符串函数

2. 链表

redis是一个设计追求简单的数据库,链表这种简单实用的数据结构在很多地方都得到了应用,(事实上应该说是双向链表。)

譬如 列表(List),慢查询,监视器,订阅与发布等。包括客户端状态也是用链表在服务器中进行保存的。

结构

typedef struct listNode {// 前置节点struct listNode *prev;// 后置节点struct listNode *next;// 节点的值void *value;} listNode;

img

img

3. 字典

字典是使用哈希表作为底层实现。

img

一图胜千言

看的出来,解决键冲突(collision)的办法是通过每个哈希表节点都是一个链表。(链地址法)

  • 哈希算法
  • 链地址法

以上两者细节就不解释了

rehash扩容

img

要扩多少内容,开多大空间的新dictEntry,然后把之前的dictEntry转到新的。

当然,一次性转会有性能问题,所以

渐进式rehash

相当于是搭便车

每次对字典进行更新添加查找删除操作时,会顺带的转移旧的dictEntry的一个index链表到新的dictEntry

详细执行过程不予介绍

4. 跳跃表(跳表)

跳跃表(skiplist)是一种有序数据结构, 它通过在每个节点中维持多个指向其他节点的指针, 从而达到快速访问节点的目的。

跳跃表支持平均 O(\log N) 最坏 O(N) 复杂度的节点查找, 还可以通过顺序性操作来批量处理节点。

在大部分情况下, 跳跃表的效率可以和平衡树相媲美, 并且因为跳跃表的实现比平衡树要来得更为简单, 所以有不少程序都使用跳跃表来代替平衡树。

Redis 使用跳跃表作为有序集合键的底层实现之一: 如果一个有序集合包含的元素数量比较多, 又或者有序集合中元素的成员(member)是比较长的字符串时, Redis 就会使用跳跃表来作为有序集合键的底层实现

img

从上图可以看书,跳表其实就是一种分治思想的,利用空间换取时间的一种算法

在看了上图之后,这个时候再看下图redis的跳表。就应该容易理解多了

img

整数集合

整数集合就比较简单了,重要的一个点主要是升级

redis的整数集合类型其实是会随着存入数字而变化的,当数都比较小的时候,类型可能就是int8_t,int16_t,但是一旦加入一个大数,集合会升级类型为相应类型,此时该集合中所有数都会被更新为该类型

另外注意

整数集合的数组不会出现降级

img

压缩列表

对象


http://chatgpt.dhexx.cn/article/7Ktrt1Xd.shtml

相关文章

(六)、Redis的AOF持久化---Redis设计与实现读书笔记

redisServer关于AOF的数据结构 /***Redis 服务器类*/ struct redisServer{...//AOF缓存区sds aof_buf;... }当服务器执行完一个写命令后,会一协议格式将被执行的写命令追加到服务器类的aof_buf缓存区的末尾。 AOF文件的写入、同步 写入、同步概念 写入&#xff…

Redis | 第8章 发布订阅与事务《Redis设计与实现》

第8章 发布订阅与事务 前言1. 发布订阅1.1 频道的订阅与退订1.2 模式的订阅与退订1.3 发送消息1.4 查看订阅消息 2. 事务2.1 事务的实现2.2 WATCH 命令的实现2.3 事务的 ACID 性质 最后 前言 参考资料:《Redis设计与实现 第二版》; 第三部分为独立功能…

AOF -- Redis 设计与实现

Redis 分别提供了 RDB 和 AOF 两种持久化机制: RDB 将数据库的快照(snapshot)以二进制的方式保存到磁盘中。AOF 则以协议文本的方式,将所有对数据库进行过写入的命令(及其参数)记录到 AOF 文件&#xff0c…

Redis设计与实现学习总结

Redis设计与实现学习总结 本文主要对Redis的设计和实现原理做了一个介绍很总结,有些东西我也介绍的不是很详细准确,尽量在自己的理解范围内把一些知识点和关键性技术做一个描述。如有错误,还望见谅,欢迎指出。 这篇文章主要还是参…

Redis的设计与实现(1):5种基本数据结构的底层实现

一、简单的动态字符串(SDS) Redis没有直接使用C语言传统的字符串表示,而是自己构建了一种名为简单动态字符串(simple dynamic string,SDS)的抽象类型,并将SDS作为Redis默认的字符串表示。 在Redis里,C字符…

Redis设计与实现总结

本文总结自《Redis设计与实现》一书,只打算总结Redis底层数据结构的实现。Redis的使用参考我的另一篇笔记Redis操作指南。 1 Redis概览 Redis是一个C语言编写的开源、非关系型内存数据库。它底层属于单线程、全内存操作,提供对象共享、引用计数和对象回…

Redis设计与实现

文章目录 第一部分:内部数据结构简单动态字符串(simple dynamic string)双端链表字典跳跃表 第二部分:内存映射数据结构整数集合intset压缩列表 redis数据类型对象处理机制(redisObject)字符串string哈希表hash列表list集合set有续集zset 第四部分&#…

redis的设计与实现

redis的设计和实现 第一部分、数据结构与对象 一、简单动态字符串: 在大多数情况下redis只会使用c字符串作为字面量,在大多情况下,redis使用SDS作为字符串表示。 比起C字符串,SDS具有五种优点: SDS结构里面会有一…

虚拟IP注册Nacos的问题

虚拟IP注册Nacos的问题 问题: A服务器有两个网卡,网卡 lo 绑定了 127.0.0.1 和一个虚拟IP,网卡 eth0 绑定了本地公网IP和一个虚拟IP。同样B服务器的网卡也是相同的配置,A、B服务器拥有的虚拟IP都是同一个地址。 当将A、B服务器部…

天翼云高可用虚拟IP(HAVIP)实践

产品概述 天翼云高可用虚拟IP(High-Availability Virtual IP Address,简称HAVIP)是一种可用独立创建和删除的私有网络IP地址资源。通过在VIP CIDR中申请一个私有网络IP地址,然后与高可用软件(如高可用软件Keepalived&…

云服务器虚拟ip绑定主机,如何在云平台上给云主机中的Keepalived的虚拟IP绑定弹性IP?...

1、 查看Keepalived和网卡配置文件中虚拟IP地址 查看虚拟机keepalived.config配置文件可以看到本地IP地址为172.16.100.109,虚拟IP地址为172.16.100.104。 (图1 Keepalived配置文件) 查看虚拟机网卡的IP地址情况,可以看到本地IP和虚拟IP。 (图2 查看虚拟…

EasyConnect虚拟IP地址未分配

工作中遇到EasyConnect虚拟IP地址未分配,导致无法正常连接服务器进行调测工作。 检查是否安装成功

蒲公英联机平台的服务器虚拟IP,蒲公英客户端如何使用固定虚拟IP管理虚拟局域网的步骤是什么?...

蒲公英异地组网分为路由器成员与客户端成员两种。其中路由器成员下的电脑,可通过本地连接获取的局域网IP进行组网通信访问;而安装并登录了蒲公英客户端成员,则是通过系统随机分配的临时虚拟IP,来进行组网成员的通讯。当成员移除原…

服务器怎么做虚拟ip,如何在服务器上添加虚拟IP?看完原来如此简单!!

写在前面最近,有位小伙伴为了实现Nginx的高可用,在自己的服务器上搭建了一套Nginx集群,Nginx节点的服务器总共有3台。那么问题来了:如何对外只使用一个IP地址,通过某种策略来访问三个服务器节点上的Nginx?答…

LNMP详解(九)——Nginx虚拟IP实战

今天继续给大家介绍Linux运维的相关知识,本文主要内容是Nginx的虚拟IP实战。 一、实战背景 在LNMP详解(七)——Nginx反向代理配置实战一文中,我们实现了如下所示的架构: 在该架构中,Nginx作为反向代理&a…

centos7 配置虚拟ip

环境概览 master:192.168.46.26 slave1:192.168.46.27 测试机:192.168.46.22(用于ping机器) 安装keepalived yum install -y keepalived修改master keepalived.conf 配置文件 vim /etc/keepalived/keepalived.confi…

计算机 修改 虚拟ip,怎么样在电脑中设置虚拟IP地址?

满意答案 wtc6981 2020.03.01 采纳率:56% 等级:9 已帮助:114人 更改IP地址 广域IP: 1、如果是PPOE上网只需断开连接再重新连上就好了,服务器会从IP地址池中随机分配一个IP地址给你。 2、固定IP上网那你要找运营商更改了,这样改是快不了的。…

虚拟服务器的真实ip,虚拟ip和真实ip区别(图文)

【导读】虚拟ip和真实ip区别,下面就是191路由网整理的网络知识百科,来看看吧! 大家好,我是191路由器网小编,上述问题将由我为大家讲解。 虚拟ip和真实ip区别是真实IP是网络运营商提供的所以不能自己变更,虚…

keepalived配置虚拟IP

YUM安装 # yum安装 yum -y install keepalived # 查看安装版本 rpm -qa keepalived # 查看安装路径 rpm -ql keepalived或是使用源码安装 到这里下载 https://www.keepalived.org/download.html # 安装依赖 yum -y install gcc openssl-devel libnfnetlink-devel 下载源码包…

虚拟ip的概念

1.虚拟IP是什么? 要是单讲解虚拟 IP,理解起来很困难,所以干脆把 动态 IP 、固定 IP 、实体 IP 与虚拟 IP都讲解一下,加深理解和知识扩展 实体 IP:在网络的世界里,为了要辨识每一部计算机的位置,因此有了计算机 IP 位址的定义。一…