读书笔记-《Redis设计与实现》(一)数据结构与对象(下)

各位朋友新年快乐~

今天我们来继续学习 Redis 。


01

整数集合

当集合仅包含整数值,并且元素数量不多时,Redis 就会采用整数集合来作为集合键的底层实现。

typedef struct intset {
    // 编码方式
    uint32_t encoding;
    
    // 元素数量
    uint32_t length;
    
    // 数组
    int8_t contents[];
} intset;

可以看到,contents 就是存储元素的地方,各个元素按从小到大排序并且不包含重复值。注意虽然 contents 声明为 int8_t,但实际类型取决于 encoding。

看到上面的数据结构,不难想到一个问题——如果现有的数组编码为 int16_t,然后往里面添加一个 int32_t 的元素,会发生什么?

答案就是升级。整数集合升级包含三个步骤:扩展数组空间、升级旧元素类型并重新放置、放置新元素。

升级的好处是:提升整体灵活性(可以任意地往里面放置不同类型的元素)、尽可能节约内存


02

压缩列表

当列表键仅包含小整数值和短字符串,并且元素数量不多时,Redis 就会采用压缩列表来作为列表键的底层实现。

压缩列表的结构如下:

  • zlbytes:记录整个列表所占内存字节数。

  • zltail:记录表尾节点距离起始位置的偏移量。

  • zllen:记录节点数量,但最大值为 UINT16_MAX(65535),超过这个值就只能通过遍历才能得到具体数量。

  • entry:各个节点,结构包括 previous_entry_length、encoding、content。第一个属性顾名思义,记录前一个节点的长度,因此程序可通过当前节点的起始地址来计算出前一个节点的起始地址,进而实现从表尾向表头的遍历;后两个属性分别为节点值的编码和节点的值。

  • zlend:末端标识符 0xFF。


03

对象

typedef struct redisObject {
    // 类型
    unsigned type:4;
    
    // 编码
    unsigned encoding:4;
    
    // 指向底层数据结构的指针
    void *ptr;
    
    // 引用计数,用于内存回收
    int refcount;
   
    // 记录最后一次被访问的时间,用于计算空转时长
    unsigned lru:22;
    
    // ...
    
} robj;

对象的关键属性如上。众所周知,Redis 包含五个对象类型,分别是字符串、列表、Hash、集合、有序集合。而我们在操作键值对时,键总是一个字符串对象,而值则可以是这五个中的任意一种。

编码则是我们前面学习的各种数据结构,例如 SDS、链表、字典、跳表、整数集合、压缩列表等等。通过这种切换编码的机制,极大提高了 Redis 的灵活性和效率

五种类型的编码如下:

  • 字符串对象:long 类型时编码为 int,字符串且长度大于39字节时为 raw(即 SDS),字符串且长度小于等于39字节时为 embstr。embstr 的特点是使用连续内存空间存储 redisObject 和 sdshdr 两个结构,减少了内存分配和回收次数,提升了读取速度。

  • 列表对象:所有字符串元素长度较小并且元素总数较少时(具体数值可配置)为 ziplist,否则为 linkedlist

  • Hash 对象:所有键值对的键和值字符串长度较小并且元素总数较少时(具体数值可配置)为 ziplist,否则为 hashtable。在使用前者时,键值对会按照顺序存放,例如依次放入键值对“hello-world”、“happy-new year”,则存储的节点顺序为 hello、world、happy、new year。

  • 集合对象:所有元素为整数值且元素总数较少时(具体数值可配置)为 intset,否则为 hashtable。在使用后者时,所有的键均没有值。

  • 有序集合对象:所有元素长度较小且元素总数较少时(具体数值可配置)为 ziplist,否则为 skiplist。特殊的点在于,使用后者时对象的结构为 zset,其同时包含一个字典和一个跳跃表,从而使得该对象在单个元素查询和范围操作时,都有着极低的时间复杂度。

了解了对象的类型和编码后,我们不难得出,Redis 的命令(如 DEL、LLEN)是多态的。前者是基于类型的多态,一个命令同时处理不同类型的键;而后者是基于编码的多态,一个命令同时处理不同的编码。

另外,Redis 还会对只包含整数值的字符串对象进行共享,即多个键指向同一个地址以节省内存。共享的数值范围(如从 0 到 9999)同样可通过配置修改。这一点对于 Java 开发来说也不陌生了,出发点和 Integer 的缓存是一样的。


原文链接:读书笔记-《Redis设计与实现》(一)数据结构与对象(下)

原创不易,点个关注不迷路哟,谢谢~

文章推荐:

  • 读书笔记-《当下的力量》
  • 读书笔记-《写给大家看的设计书》
  • 赛博朋克2077玩后感
  • 程序员工作中常见问题,你遇到过几个?
  • 如何设计离线跑批系统
  • 读书笔记-《人人都是产品经理》
  • 如何养成好习惯
  • 读书笔记-《最好的告别》
  • 读书笔记-《Spring技术内幕》(四)事务
  • 读书笔记-《Redis设计与实现》(一)数据结构与对象(上)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/962340.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

IP服务模型

1. IP数据报 IP数据报中除了包含需要传输的数据外,还包括目标终端的IP地址和发送终端的IP地址。 数据报通过网络从一台路由器跳到另一台路由器,一路从IP源地址传递到IP目标地址。每个路由器都包含一个转发表,该表告诉它在匹配到特定目标地址…

上海亚商投顾:沪指冲高回落 大金融板块全天强势 上海亚商投

上海亚商投顾前言:无惧大盘涨跌,解密龙虎榜资金,跟踪一线游资和机构资金动向,识别短期热点和强势个股。 一.市场情绪 市场全天冲高回落,深成指、创业板指午后翻绿。大金融板块全天强势,天茂集团…

数据分析系列--④RapidMiner进行关联分析(案例)

一、核心概念 1.项集(Itemset) 2.规则(Rule) 3.支持度(Support) 3.1 支持度的定义 3.2 支持度的意义 3.3 支持度的应用 3.4 支持度的示例 3.5 支持度的调整 3.6 支持度与其他指标的关系 4.置信度&#xff0…

HTB靶场Adminstrator

文章目录 靶机信息域环境初步信息收集与权限验证FTP 登录尝试SMB 枚举尝试WinRM 登录olivia域用户枚举 获取Michael权限BloodHound 提取域信息GenericAll 获取Benjamin权限ForceChangePasswordftp登录benjamin 获取Emily权限pwsafehashcat 获取Ethan权限获取管理员(Administrat…

C语言指针专题三 -- 指针数组

目录 1. 指针数组的核心原理 2. 指针数组与二维数组的区别 3. 编程实例 4. 常见陷阱与防御 5. 总结 1. 指针数组的核心原理 指针数组是一种特殊数组,其所有元素均为指针类型。每个元素存储一个内存地址,可指向不同类型的数据(通常指向同…

Spring Boot - 数据库集成06 - 集成ElasticSearch

Spring boot 集成 ElasticSearch 文章目录 Spring boot 集成 ElasticSearch一:前置工作1:项目搭建和依赖导入2:客户端连接相关构建3:实体类相关注解配置说明 二:客户端client相关操作说明1:检索流程1.1&…

深入理解MySQL 的 索引

索引是一种用来快速检索数据的一种结构, 索引使用的好不好关系到对应的数据库性能方面, 这篇文章我们就来详细的介绍一下数据库的索引。 1. 页面的大小: B 树索引是一种 Key-Value 结构,通过 Key 可以快速查找到对应的 Value。B 树索引由根页面(Root&am…

vue之pinia组件的使用

1、搭建pinia环境 cnpm i pinia #安装pinia的组件 cnpm i nanoid #唯一id,相当于uuid cnpm install axios #网络请求组件 2、存储读取数据 存储数据 >> Count.ts文件import {defineStore} from piniaexport const useCountStore defineStore(count,{// a…

【MySQL — 数据库增删改查操作】深入解析MySQL的 Update 和 Delete 操作

1. 测试数据 mysql> select* from exam1; ----------------------------------------- | id | name | Chinese | Math | English | ----------------------------------------- | 1 | 唐三藏 | 67.0 | 98.0 | 56.0 | | 2 | 孙悟空 | 87.0 | 78.…

数据结构与算法之二叉树: LeetCode LCP 10. 二叉树任务调度 (Ts版)

二叉树任务调度 https://leetcode.cn/problems/er-cha-shu-ren-wu-diao-du/description/ 描述 任务调度优化是计算机性能优化的关键任务之一。在任务众多时,不同的调度策略可能会得到不同的总体执行时间,因此寻求一个最优的调度方案是非常有必要的 通…

JAVA 接口、抽象类的关系和用处 详细解析

接口 - Java教程 - 廖雪峰的官方网站 一个 抽象类 如果实现了一个接口,可以只选择实现接口中的 部分方法(所有的方法都要有,可以一部分已经写具体,另一部分继续保留抽象),原因在于: 抽象类本身…

游戏引擎 Unity - Unity 启动(下载 Unity Editor、生成 Unity Personal Edition 许可证)

Unity Unity 首次发布于 2005 年,属于 Unity Technologies Unity 使用的开发技术有:C# Unity 的适用平台:PC、主机、移动设备、VR / AR、Web 等 Unity 的适用领域:开发中等画质中小型项目 Unity 适合初学者或需要快速上手的开…

【基于SprintBoot+Mybatis+Mysql】电脑商城项目之用户注册

🧸安清h:个人主页 🎥个人专栏:【计算机网络】【Mybatis篇】 🚦作者简介:一个有趣爱睡觉的intp,期待和更多人分享自己所学知识的真诚大学生。 目录 🎯项目基本介绍 🚦项…

视频多模态模型——视频版ViT

大家好,这里是好评笔记,公主号:Goodnote,专栏文章私信限时Free。本文详细解读多模态论文《ViViT: A Video Vision Transformer》,2021由google 提出用于视频处理的视觉 Transformer 模型,在视频多模态领域有…

DeepSeek本地部署(windows)

一、下载并安装Ollama 1.下载Ollama Ollama官网:Ollama 点击"Download",会跳转至下载页面。 点击"Download for Windows"。会跳转Github进行下载,如下载速度过慢,可在浏览器安装GitHub加速插件。 2.安装Ollama 双击下载的安装文件,点击"Inst…

1 HDFS

1 HDFS 1. HDFS概述2. HDFS架构3. HDFS的特性4. HDFS 的命令行使用5. hdfs的高级使用命令6. HDFS 的 block 块和副本机制6.1 抽象为block块的好处6.2 块缓存6.3 hdfs的文件权限验证6.4 hdfs的副本因子 7. HDFS 文件写入过程(非常重要)7.1 网络拓扑概念7.…

全国31省空间权重矩阵(地理相邻空间、公路铁路地理距离空间、经济空间)权重矩阵数据-社科数据

中国31个省份空间权重矩阵-社科数据https://download.csdn.net/download/paofuluolijiang/90028597 https://download.csdn.net/download/paofuluolijiang/90028597 空间权重矩阵是反映个体在空间中依赖关系的矩阵,本数据计算全国31个省三种标准化处理的空间权重矩…

Flask框架基础入门教程_ezflaskapp

pip install flaskFlask 快速入门小应用 学东西,得先知道我们用这个东西,能做出来一个什么东西。 一个最小的基于flask 的应用可能看上去像下面这个样子: from flask import Flask app Flask(__name__)app.route(/) def hello_world():ret…

机器学习笔记——特征工程

大家好,这里是好评笔记,公主号:Goodnote,专栏文章私信限时Free。本笔记介绍机器学习中常见的特征工程方法、正则化方法和简要介绍强化学习。 文章目录 特征工程(Fzeature Engineering)1. 特征提取&#xff…

Cursor火出圈,未来程序员还有出路吗?

大家好,我是凡人。 今天我表弟家邻居的阿姨,托他问问我目前程序员还有前景吗,希望我根据十几年的经验给出点建议,看看程序员这条路未来能不能走。 一下子不知道该怎么回复他了,如果是三年前问我,肯定毫不…