redis 数据结构String之SDS

news2024/11/16 12:00:03

redis字符串(String)内存结构:

字符串对象底层数据结构实现为简单动态字符串(SDS)和直接存储,但其编码方式可以是int、raw或者embstr,区别在于内存结构的不同。

  1. int编码
    字符串保存的是整数值,并且这个正式可以用long类型来表示,那么其就会直接保存在redisObject的ptr属性里,并将编码设置为int

  2. raw编码
    字符串保存的小于44字节的字符串值,则使用简单动态字符串(SDS)结构,并将编码设置为raw,此时内存结构与SDS结构一致,内存分配次数为两次,创建redisObject对象和sdshdr结构。

  3. embstr编码
    字符串保存的小于等于32字节的字符串值,使用的也是简单的动态字符串(SDS结构),但是内存结构做了优化,用于保存顿消的字符串;内存分配也只需要一次就可完成,分配一块连续的空间即可。

在Redis中,存储long、double类型的浮点数是先转换为字符串再进行存储的
raw与embstr编码效果是相同的,不同在于内存分配与释放,raw两次,embstr一次
embstr 编码的字符串对象的所有数据都保存在一块连续的内存里面, 所以这种编码的字符串对象比起 raw 编码的字符串对象能够更好地利用缓存带来的优势
int编码和embstr编码如果做追加字符串等操作,满足条件下会被转换为raw编码;embstr编码的对象是只读的,一旦修改会先转码到raw

SDS
在redis中,包含字符串的键值都是由SDS实现的


struct sdshdr{
     //字节数组
     char buf[]; 
     //buf数组中已使用字节数量
     int len;
     //buf数组中未使用字节数量
     int free;
}


struct __attribute__ ((__packed__)) sdshdr8 {
    uint8_t len; // 字符串长度
    uint8_t alloc; // 分配的空间长度
    unsigned char flags; // sds类型 8 16 32 64
    char buf[]; // 字节数组,用来保存实际的字符串
};
struct __attribute__ ((__packed__)) sdshdr16 {
    uint16_t len; /* used */
    uint16_t alloc; /* excluding the header and null terminator */
    unsigned char flags; /* 3 lsb of type, 5 unused bits */
    char buf[];
};

为什么使用SDS

  1. 相比C语言字符串,使获取字符串长度时间复杂度降为O(1)
    len 属性
    如:访问当前字符串的长度,直接读取即可,时间复杂度0(1)。C语言字符串不记录自身长度,如果想获取自身长度必须遍历整个字符串,对每个字符进行计数,这个操作时间复杂度是O(n)。

  2. 空间预知分配,惰性空间释放
    alloc 属性。
    可以用来计算free,用来计算字符串未使用的空间。
    空间预分配
    SDS修改后,len长度小于1M,那么将会额外分配与len相同的未使用空间。如果修改后长度大于1M,那么将分配1M的使用空间。
    惰性释放
    有空间分配对应就有空间释放。SDS缩短时,并不会回收多余的内存空间,而是使用free字段将空出来的空间记录下来,如果后续有变更操作,直接使用free,减少了内存的分配次数。

  3. 二进制安全
    二进制数据并不是规划的字符串格式,可能会包含一些特殊字符。比如“\0”,
    c中字符串遇到“\0”会结束,那“\0”之后的数据就读取不上了。
    SDS根据len长度来判断字符串结束的,二进制安全问题就解决了。

int, emb,raw详解

int
redis 启动时会预先简历 10000个分别存储0-9999的redisObject 变量作为共享对象,这意味着如果set字符窜的键值在0-10000之间的话,则可以直接指向共享对象而不需要建立新对象,此时v 不占空间。
比如 set k1 123 set k2 123
也就是 k1,k2 只想的是同一个RedisObject 对象
与JAVA Integer (-128 to 127)类似。

emb
对于长度小于44的字符串,Redis对键值采用OBJ_ENCODING_EMBSTR方式,EMBSTR表示sds结构体与其对应的redisObject对象分配在同一块连续的内存空间,字符串SDS嵌入在redisObject对象之中一样。实现了内存的连续紧密的空间。

在这里插入图片描述
raw
当字符串的键值为长度大于44的超长字符串时,redis则会将键值的内部编码改为OBJ_ENCODING_RAW,这与OBJ_ENCODING_EMBSTR编码方式的不同之处在于,此时动态字符串sds的内存与其依赖的redisObject的内存不在连续了。也就是重新分配了内存。
在这里插入图片描述
注意
对于embstr, 由于其实现是只读的,因此在对embstr对象进行修改是,都会先转化为raw,再进行修改,因此,只是修改embstr对对象,修改后的对象一定是raw,无论是否达到了44字节。
比如 set k3 a , append k3 b, 那么k3 则为 raw。

在这里插入图片描述

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

iOS 16 UI 设计系统免费在线使用方法

1、iOS 16 UI 设计系统中有什么? iOS 16 UI 设计系统通常包含以下组件和元素: 1. 按钮:包括操作按钮、图标按钮、导航按钮、滚动按钮、切换按钮、单选按钮、复选框按钮、呼叫按钮等各种类型的按钮。 2. 窗口和 UI 控件:包括标签…

JAVA变量在不同情况下未赋值与默认初始值

目录 一、默认初始值 二、本地变量 代码 运行结果 二、实例变量 代码 运行结果 三、本地变量和实例变量的区别 1.作用域 2.生命周期 3.初始化 一、默认初始值 数据类型初始值数据类型初始值byte0long0Lchar‘u0000’float0.0fshort0double0.0int0booleanfalse引用nul…

人工智能-机器学习人工神经网络

机器学习 机器学习部分主要学习的内容是朴素贝叶斯算法和决策树算法。 决策树算法 决策树算法是机器学习中常用的一种分类算法,在决策树中,使用各个属性进行分类,选取每次分类的属性的方式有多种。最简单的是ID3算法,使用信息增…

【论文阅读】Robust Object-based SLAM for High-speed Autonomous Navigation

一、问题概述 这篇文章是在QuadricSLAM的基础上进行的改进,也就是说依然使用了椭球对物体进行描述,论文中提到使用椭球本身是因为椭球其参数化表示可以完全通过相机的检测框来进行约束,二次曲面与对偶二次曲面可以参考链接,文章使…

uniapp-前端 二维码、扫码、长按、识别等问题

一&#xff1a;识别&#xff1a;图片二维码url&#xff1a; 后端返回二维码的图片url&#xff0c;则直接展示&#xff0c;做长按手势识别&#xff0c;再调用方法即可。 <mage>标签长按识别实现&#xff08;微信版本>2.7.0&#xff09; <image show-menu-by-long…

JS数组题

从0到1&#xff1a;JavaScript快速上手第六章课后习题 一、单选题1&#xff0e;下面有一个数组&#xff0c;该数组中数值最小和数值最大的元素的下标分别是&#xff08; &#xff09;。 var arr[3,9,1,12,36,50,21] A&#xff0e;2, 5 B&#xff0e;3, 6 C&#xff0e;2, 6 D&…

【刷题】144. 二叉树的前序遍历

144. 二叉树的前序遍历 一、题目描述二、示例三、实现总结 144. 二叉树的前序遍历 一、题目描述 给你二叉树的根节点 root &#xff0c;返回它节点值的 前序 遍历。 二、示例 示例1&#xff1a; 输入&#xff1a;root [1,null,2,3] 输出&#xff1a;[1,2,3] 示例 2&#…

第十五章行为性模式—命令模式

文章目录 命令模式解决的问题结构实例存在的问题适用场景 JDK 源码 - Runnable 行为型模式用于描述程序在运行时复杂的流程控制&#xff0c;即描述多个类或对象之间怎样相互协作共同完成单个对象无法单独完成的任务&#xff0c;它涉及算法与对象间职责的分配。行为型模式分为类…

OW-DETR: Open-world Detection Transformer(论文翻译)

文章目录 OW-DETR: Open-world Detection Transformer摘要1.介绍2.开放世界检测的transformer2.1整体架构2.2.多尺度上下文编码2.3.注意力驱动的伪标签2.4 新类分类2.5.前景物体2.6.训练与推理 3.实验3.1.最新技术水平比较3.2.增量目标检测3.3 消融实验 4.与现有技术的关系5.结…

【干货收藏】 隔离驱动SLMi335/SLMi335H 电路方案分享

数明深力科SLMi33X系列SLMi335/SLMi335H首款单通道带DESAT保护功能的IGBT/SiC隔离驱动器。内置快速去饱和(DESAT) 故障检测功能、米勒钳位功能、漏极开路故障反馈、软关断功能以及可选择的自恢复模式&#xff0c;兼容光耦隔离驱动器。 SLMi33X系列SLMi335/SLMi335H的DESAT阈值…

如何搭建高质量的 B 端产品帮助体系?

在B2B市场中&#xff0c;产品的质量和支持服务对于企业的成功至关重要。帮助中心是B2B企业提供优质支持服务的重要组成部分。那么&#xff0c;如何搭建高质量的B端产品帮助体系呢&#xff1f;本文将为大家介绍一些关键的步骤和方法。 一、了解用户需求 首先&#xff0c;要搭建…

【ZYNQ】QSPI Flash 固化程序全攻略

普通的 FPGA 一般是可以从 Flash 启动&#xff0c;或者被动加载&#xff0c;ZYNQ 的启动是由 ARM 主导的&#xff0c;包括 FPGA 程序的加载&#xff0c;ZYNQ 启动一般为最少两个步骤&#xff0c;在 UG585 中也有介绍。 Stage 0&#xff1a;BootROM 阶段 在 ZYNQ 上电复位或者热…

前端异步请求并解决跨域问题(Ajax+axios框架)、后端响应多个数据(JSON)

目录 一、前后端同步异步请求 1.同步请求&#xff1a; 2.异步请求&#xff1a; 3.跨域问题&#xff08;前端问题&#xff09; 4.axios框架&#xff08;封装后&#xff09; 二、后端向前端响应多个数据-JSON 一、前后端同步异步请求 1.同步请求&#xff1a; 发送一个请求…

【Java多线程进阶】CAS机制

前言 CAS指的是Compare-And-Swap&#xff08;比较与交换&#xff09;&#xff0c;它是一种多线程同步的技术&#xff0c;常用于实现无锁算法&#xff0c;从而提高多线程程序的性能和扩展性。本篇文章具体讲解如何使用 CAS 的机制以及 CAS 机制带来的问题。 目录 1. 什么是CAS&…

《机器学习算法竞赛实战》-chapter4特征工程

《机器学习算法竞赛实战》学习笔记&#xff0c;记录一下自己的刷题过程&#xff0c;详细的内容请大家购买作者的书籍查阅。 特征工程 特征工程是算法竞赛中工作量最大&#xff0c;决定参赛者能否拿到较好名次的关键部分。吴恩达老师说过&#xff1a;“机器学习在本质上还是特…

Maven Compile时报错 [ERROR] [X Group Enforcer Rules] find DuplicateClasses

类冲突 [ERROR] [Ctrip Group Enforcer Rules] find DuplicateClasses Found in: net.jpountz.lz4:lz4:jar:1.3.0:compile org.lz4:lz4-java:jar:1.7.1:compile Duplicate classes: net/jpountz/xxhash/AbstractStreamingXXHash32Java.class net/jpountz/lz4/LZ4BlockInputStre…

Arduino+ESP8266 MCU开发板 ----带你开发 (TCP)双向局域网通信 项目-----可开发成为小远程控制

目录 本次需要下载的代码链接&#xff1a; 文章项目引用&#xff1a;本次实现可依据之前的文章就行举一反三的操作 本次开发项目步1&#xff1a;下载Aeduino软件 本次开发项目步2&#xff1a; 更替代码片段1 第13行 代替账号和密码 更替代码片段2 第20行 …

软件科技项目验收有哪些注意事项?第三方软件验收测试的好处在哪?

软件科技项目的验收是软件生产周期中非常重要的一个环节。它主要目的是验证软件产品是否满足用户需求&#xff0c;达到预期的质量和性能要求。因此&#xff0c;在进行软件科技项目验收时&#xff0c;有一些注意事项需要遵循。 一、软件科技项目验收的注意事项 1、明确验收标准…

JS使用随机数生成随机验证码

一 随机数测试 在JavaScript中&#xff0c;我们可以使用random&#xff08; &#xff09;方法来生成0&#xff5e;1的一个随机数。random&#xff0c;就是“随机”的意思。需要注意的是&#xff0c;这里的0&#xff5e;1包含0但不包含1&#xff0c;也就是[0, 1&#xff09;。在…

ubuntu20.04 ROS 环境下使用velodyne激光雷达

ROS 环境下使用velodyne激光雷达 系统版本:ubuntu 20.04 ROS版本&#xff1a;noetic 激光雷达型号&#xff1a;velodyne VLP-16 1.系统环境配置 sudo apt install ros-noetic-velodyne #安装ROS依赖 mkdir-p velodyne_ws/src …