当前位置: 首页 > news >正文

从源码看 Redis:深入理解 redisDb 和 redisObject

Redis 是一个广泛使用的内存数据库,以其高性能和丰富的数据结构而闻名。不同于磁盘数据库,磁盘数据库将数据读取到文件中维护,而内存数据库将数据存储在内存中,意味着其想要维护数据,必须在代码中维护一个保存数据的结构,而redis由c语言编写,对应的其一定是通过结构体来保存数据的结构。

redisDb结构体

在redis源码中,每个redisDb结构体代表着一个数据库,结构体大致如下

typedef struct redisDb {dict *dict;                 dict *expires;              dict *blocking_keys;        dict *ready_keys;           dict *watched_keys;         int id;                     long long avg_ttl;          unsigned long expires_cursor; 
} redisDb;

让我们来一个一个解释其意义

dict:

数据字典,其中保存了所有存入的数据,在redis中没有表的概念,数据作为键值对存储,直接存入数据库中,以hash表的结构存储,我在讲解redis中五个基本数据类型中详细讲解了hash表的结构,想了解可以看我的这篇文章Redis五种数据类型,底层存储数据结构,以及相关命令。

expire:

这也是一个数据字典,不同的是,其存储的是key和其对应的过期时间(时间戳)。将过期时间单独存储,有利于redis便利key查找过期key(有的key不设过期时间,单独存储可以防止便利这些没有过期时间的key)

blocking_keys:

这仍然是一个数据字典,其中保存的是正在阻塞等待中的key,比如说一个客户端对一个list数据使用了blpop命令,但list没有数据,此时客户端就会进入阻塞状态,等待list插入数据,当多个客户端都对一个空的list使用blpop命令,那么则需要一个结构来维护他们的先后关系,blocking_keys的作用就是维护阻塞key和等待其数据的客户端的先后关系。

ready_keys:

这也是一个数据字典,当blocking_keys中维护的key有新数据插入时(每次插入数据都会检查是否包含在blocking_keys中),会讲对应的key放入ready_keys中,等待当前事件循环中的插入数据操作完成后,在便利ready_key获取key,并且根据这个key在block_keys和dict中获取客户端和值并且发送(高并发情况下,一次会有大量的插入操作,先执行完当前事件循环的插入操作,并且放入ready_keys中,插入操作完成后再统一返回给客户端)。当使用publish发布订阅消息时,订阅消息也会放入ready_keys中,与blpop不同的是,所有订阅这个消息的客户端都会收到这个消息,没有先后顺序一分,所以不需要维护客户端的先后关系,也就不需要进入block_keys。

watched_keys:

当我们使用redis开启一个事务时,我们需要先确定这个事务依赖于哪些key,然后通过watch key1 key2 ... 的命令来监控这些key,那么当前这个事务就会作为这些key的value被保存在watched_keys中,当对key进行修改操作时,会去查看watch_keys中是否有这个key,如果有,则将key对应的全部事务进行取消。并且便利watched_keys将其他key中保存的当前事务删除。

id:

唯一id,没什么好说的。

avg_ttl:

保存expire中保存的过期时间的平均值,每当平均时间改变时都要重新计算一次。

expires_cursor:

当前便利位置的游标,redis内存淘汰过程中需要便利检查key是否过期,不过大量的key一次性遍历势必会造成程序卡顿,为了防止这种情况,在周期性模式下,一次性会检查一部分key,然后保存当前位置作为游标,下次检查时会接着游标的位置继续遍历。

结构体示意图如下

50fb79d4ead7456a841ad58316756638.png

redisObject

我们在redisDB结构体的中dict数据字典中保存的都是key和数据,而数据的结构则是redisObject,同redisDB一样,redisObject也是一个结构体,代码如下

typedef struct redisObject {unsigned type:4;         unsigned encoding:4;         unsigned lru:LRU_BITS;   int refcount;            void *ptr;               
};

type:

对象类型,也就是redis五大基本数据类型以及两个高级数据类型(bitmap和hyperloglog底层是string类型,而geo底层是zset类型),其中包括REDIS_STRING,REDIS_LIST,REDIS_SET,REDIS_ZSET,REDIS_HASH,REDIS_MODULE,REDIS_STREAM

encoding:

编码方式,简单来说redis基本数据类型的保存也要精心设计来提高其内部属性的操作性能,因为一个基本数据类型内部也保存了大量的元素或键值对,而编码方式就是某个类型用了什么样的数据结构来保存其内部的键值对或元素,其中包括SDS,整数列表,压缩列表,双向链表,快速列表,hash表,跳表。想了解更多可以看我的另一个文章Redis五种数据类型,底层存储数据结构,以及相关命令https://blog.csdn.net/dxh9231028/article/details/140824108

lru:

在基于LRU算法的内存淘汰策略下保存过期时间戳,在基于LFU算法德内存淘汰策略下保存的时一个代表访问频率高低整数(不是访问次数),想了解具体内容可以看我的另一篇帖子redis-过期key删除,内存淘汰策略,内存碎片化处理https://blog.csdn.net/dxh9231028/article/details/138451287?csdn_share_tail=%7B%22type%22%3A%22blog%22%2C%22rType%22%3A%22article%22%2C%22rId%22%3A%22138451287%22%2C%22source%22%3A%22dxh9231028%22%7D

refcount:

引用计数,用于内存管理。当引用计数为 0 时,表示没有任何地方引用该对象,内存可以被回收。

ptr:

指向实际数据值的指针。实际数据的类型和结构取决于 typeencoding 字段的值。比如说如果是string类型,那么就可以指向一个SDS结构体的对象,如果是hash类型,有可能会指向一个hash表等等。

 

相关文章:

从源码看 Redis:深入理解 redisDb 和 redisObject

Redis 是一个广泛使用的内存数据库,以其高性能和丰富的数据结构而闻名。不同于磁盘数据库,磁盘数据库将数据读取到文件中维护,而内存数据库将数据存储在内存中,意味着其想要维护数据,必须在代码中维护一个保存数据的结…...

unity中实现流光效果——世界空间下

Properties{_MainTex ("Texture", 2D) "white" {}_FlowColor ("Flow Color", Color) (1, 1, 1, 1) // 流光颜色_FlowFrequency ("Flow Frequency", Float) 1.0 // 流光频率_FlowSpeed ("Flow Speed", Float) 1.0 // 流光…...

项目经验分享:用4G路由器CPE接海康NVR采用国标GB28181协议TCP被动取流一段时间后设备就掉线了

最近我们在做一个生态化养殖的项目时,发现一个奇怪的现象: 项目现场由于没有有线网络,所以,我们在现场IPC接入到海康NVR之后,再通过一款4G的CPE接入到天翼云的国标GB28181视频平台;我们采用UDP协议播放NVR…...

【RabbitMQ】RabbitMQ不公平分发_预取值

一、不公平分发 1、简介 RabbitMQ中的不公平分发(Unfair Dispatch)是指当多个消费者(Consumers)同时订阅同一个队列(Queue)时,消息的分发机制并非严格平均或公平,而是基于某些条件…...

最新AI模型使用指南和模型

市面上最好的AI大模型 OpenAI GPT-4: 概述:GPT-4 是 OpenAI 发布的最新一代大型语言模型,具备更强的理解和生成自然语言的能力。特点: 强大的文本生成和理解能力。支持多语言处理。可用于各种应用场景,如对话生成、内容…...

数据结构之八大基本排序方法

在数据结构中,排序是一个重要的操作,它有助于提高数据的可读性和可操作性。排序算法有多种,各有优缺点,适用于不同的场景。以下是八大经典排序算法的介绍: 1. 冒泡排序(Bubble Sort) 原理&…...

《Milvus Cloud向量数据库指南》——什么是高可用:深入理解数据库系统中的高可用性架构

什么是高可用:深入理解数据库系统中的高可用性架构 在信息技术日新月异的今天,高可用性(High Availability,简称HA)已成为衡量一个系统,尤其是数据库系统稳定性和可靠性的重要标准。高可用性的核心目标在于确保系统能够持续不断地提供服务,最大限度地减少因维护活动、硬…...

C++ | Leetcode C++题解之第319题灯泡开关

题目: 题解: class Solution { public:int bulbSwitch(int n) {return sqrt(n 0.5);} };...

C# 使用 NLog 输出日志到文件夹

在项目中使用 NuGet 安装 NLog 包以及 NLog.Config 包 配置 nlog.config 在项目的根目录下创建一个 Nlog.config 文件&#xff08;如果还没有&#xff09;&#xff0c;然后添加如下配置&#xff1a; <?xml version"1.0" encoding"utf-8" ?> <…...

node.js使用NodeMachineID 生成唯一UUID和注意事项

node-machine-id用于获取或生成唯一的机器ID 如何使用 const { machineId, machineIdSync } require(node-machine-id) JSON.stringify(machineIdSync({original: true})) ;方法&#xff1a; machineIdSync 此函数同步获取操作系统本机UUID/GUID&#xff0c;默认情况下进行哈…...

AI大模型在数据治理中的应用

目前&#xff0c;企业的数据治理工作以人工实施为主&#xff0c;其中一些重复性较强的工作&#xff0c;如&#xff1a;数据标准制定和映射、元数据信息完善、数据目录挂载等&#xff0c;需要消耗大量的人力和时间成本&#xff0c;这给本来就难以量化业务价值的治理工作的顺利推…...

【初学人工智能原理】【12】循环:序列依赖问题

前言 本文教程均来自b站【小白也能听懂的人工智能原理】&#xff0c;感兴趣的可自行到b站观看。 代码及工具箱 本专栏的代码和工具函数已经上传到GitHub&#xff1a;1571859588/xiaobai_AI: 零基础入门人工智能 (github.com)&#xff0c;可以找到对应课程的代码 正文 对于…...

【QT】无法打开QT的ui文件,出现闪退情况

打开qt的ui文件出现闪退的情况&#xff1a; 解决办法&#xff1a;点击扩展-Qt VS Tools-Options 找到Qt General中的Qt Designer 的Run in detached window改为True。...

三、Spring-WebFlux实战案例-流式

目录 一、springboot之间通讯方式 1. 服务端 (Spring Boot) 1.1 添加依赖 1.2 控制器 2. 客户端 (WebClient) 2.1 添加依赖 2.2 客户端代码 3. 运行 二、web与服务之间通讯方式 1、服务端代码 2、客户端代码 3、注意事项 三、移动端与服务端之间通讯方式…...

html+css 实现hover双层按钮

前言&#xff1a;哈喽&#xff0c;大家好&#xff0c;今天给大家分享htmlcss 绚丽效果&#xff01;并提供具体代码帮助大家深入理解&#xff0c;彻底掌握&#xff01;创作不易&#xff0c;如果能帮助到大家或者给大家一些灵感和启发&#xff0c;欢迎收藏关注哦 &#x1f495; 文…...

SPIFFS与LittleFS的对gz文件格式的区别

SPIFFS 只能安装在Arduino上。LittleFS支持Arduino IDE和VScode的 PlatformIO。 SPIFFS serveStatic: server.serveStatic("/", SPIFFS, "/") 负责提供 SPIFFS 文件系统中的文件。您可以在 SPIFFS 上放置 .gz 文件&#xff0c;并该方法将自动处理它们。 …...

STM32L051K8U6-开发资料

STM32L051测试 &#xff08;四、Flash和EEPROM的读写&#xff09;-云社区-华为云 (huaweicloud.com) STM32L051测试 &#xff08;四、Flash和EEPROM的读写&#xff09; - 掘金 (juejin.cn) STM32L0 系列 EEPROM 读写&#xff0c;程序卡死&#xff1f;_stm32l0片内eeprom_stm3…...

Markdown语法学习

Markdown学习 一、基础语法讲解 1. 换行 本行末尾双空格然后回车&#xff08;在Typora的中直接回车也可以&#xff09; 2. 换段 本段末尾两次回车 3. 加粗 **加粗** __加粗__效果&#xff1a;加粗 4. 斜体 *加粗* _加粗_效果&#xff1a;斜体 5. 斜体加粗 ***加粗**…...

[最短路Floyd],启动!!!

B3647 【模板】Floyd #include<bits/stdc.h> #define ll long long #define fi first #define se second #define pb push_back #define PII pair<int,int > #define IOS ios::sync_with_stdio(false),cin.tie(0),cout.tie(0) using namespace std; const int N …...

7月29(信息差)

&#x1f30d;最强模型 Llama 3.1 如期而至&#xff01;扎克伯格最新访谈&#xff1a;Llama 会成为 AI 界的 Linux &#x1f384;谷歌AlphaProof攻克国际奥赛数学题 https://www.51cto.com/article/793632.html ✨SearchGPT第一波评测来了&#xff01;响应速度超快还没广告&…...

Flask RESTful 示例

目录 1. 环境准备2. 安装依赖3. 修改main.py4. 运行应用5. API使用示例获取所有任务获取单个任务创建新任务更新任务删除任务 中文乱码问题&#xff1a; 下面创建一个简单的Flask RESTful API示例。首先&#xff0c;我们需要创建环境&#xff0c;安装必要的依赖&#xff0c;然后…...

MySQL 隔离级别:脏读、幻读及不可重复读的原理与示例

一、MySQL 隔离级别 MySQL 提供了四种隔离级别,用于控制事务之间的并发访问以及数据的可见性,不同隔离级别对脏读、幻读、不可重复读这几种并发数据问题有着不同的处理方式,具体如下: 隔离级别脏读不可重复读幻读性能特点及锁机制读未提交(READ UNCOMMITTED)允许出现允许…...

条件运算符

C中的三目运算符&#xff08;也称条件运算符&#xff0c;英文&#xff1a;ternary operator&#xff09;是一种简洁的条件选择语句&#xff0c;语法如下&#xff1a; 条件表达式 ? 表达式1 : 表达式2• 如果“条件表达式”为true&#xff0c;则整个表达式的结果为“表达式1”…...

渲染学进阶内容——模型

最近在写模组的时候发现渲染器里面离不开模型的定义,在渲染的第二篇文章中简单的讲解了一下关于模型部分的内容,其实不管是方块还是方块实体,都离不开模型的内容 🧱 一、CubeListBuilder 功能解析 CubeListBuilder 是 Minecraft Java 版模型系统的核心构建器,用于动态创…...

SAP学习笔记 - 开发26 - 前端Fiori开发 OData V2 和 V4 的差异 (Deepseek整理)

上一章用到了V2 的概念&#xff0c;其实 Fiori当中还有 V4&#xff0c;咱们这一章来总结一下 V2 和 V4。 SAP学习笔记 - 开发25 - 前端Fiori开发 Remote OData Service(使用远端Odata服务)&#xff0c;代理中间件&#xff08;ui5-middleware-simpleproxy&#xff09;-CSDN博客…...

安宝特方案丨船舶智造的“AR+AI+作业标准化管理解决方案”(装配)

船舶制造装配管理现状&#xff1a;装配工作依赖人工经验&#xff0c;装配工人凭借长期实践积累的操作技巧完成零部件组装。企业通常制定了装配作业指导书&#xff0c;但在实际执行中&#xff0c;工人对指导书的理解和遵循程度参差不齐。 船舶装配过程中的挑战与需求 挑战 (1…...

LangChain知识库管理后端接口:数据库操作详解—— 构建本地知识库系统的基础《二》

这段 Python 代码是一个完整的 知识库数据库操作模块&#xff0c;用于对本地知识库系统中的知识库进行增删改查&#xff08;CRUD&#xff09;操作。它基于 SQLAlchemy ORM 框架 和一个自定义的装饰器 with_session 实现数据库会话管理。 &#x1f4d8; 一、整体功能概述 该模块…...

深入浅出深度学习基础:从感知机到全连接神经网络的核心原理与应用

文章目录 前言一、感知机 (Perceptron)1.1 基础介绍1.1.1 感知机是什么&#xff1f;1.1.2 感知机的工作原理 1.2 感知机的简单应用&#xff1a;基本逻辑门1.2.1 逻辑与 (Logic AND)1.2.2 逻辑或 (Logic OR)1.2.3 逻辑与非 (Logic NAND) 1.3 感知机的实现1.3.1 简单实现 (基于阈…...

【学习笔记】erase 删除顺序迭代器后迭代器失效的解决方案

目录 使用 erase 返回值继续迭代使用索引进行遍历 我们知道类似 vector 的顺序迭代器被删除后&#xff0c;迭代器会失效&#xff0c;因为顺序迭代器在内存中是连续存储的&#xff0c;元素删除后&#xff0c;后续元素会前移。 但一些场景中&#xff0c;我们又需要在执行删除操作…...

HubSpot推出与ChatGPT的深度集成引发兴奋与担忧

上周三&#xff0c;HubSpot宣布已构建与ChatGPT的深度集成&#xff0c;这一消息在HubSpot用户和营销技术观察者中引发了极大的兴奋&#xff0c;但同时也存在一些关于数据安全的担忧。 许多网络声音声称&#xff0c;这对SaaS应用程序和人工智能而言是一场范式转变。 但向任何技…...