Redis的SDS你了解吗?

初识SDS:

Redis的String和其他很多编程语言中的语义相似,它能够表达3种值的类型:

1.字符串
2.整数
3.浮点数

三种类型根据具体场景由Redis完成相互之间的自动转换,并且根据需要选取底层的承载方式,Redis内部,String类型的value是用int,SDS作为结构存储int用来存放整型数据SDS存放字节/字符串和浮点型数据。相较于C的标准字符串,SDS封装了更多的信息以提升基本操作的性能,同时充分利用已有的C的标准库,简化实现。

Redis也支持使用C语言的传统字符串,只不过会用在一些不需要对字符串修改的地方,比如静态的字符输出,而我们开发中使用Redis,往往会经常性的修改字符串的值,这个时候就会用SDS来表示字符串的值了。

在redis数据库中,K-V键值对含有字符串值的,都是由SDS来实现的。

一个SDS值的数据结构,主要由len,free,buf[]这三个属性组成

struct sdshdr{int free;//buf[]数组未使用字节的数量int len;//buf[]数组所保存的字符串的长度char buf[];//保存字符串的数组
}

其中buf[]为实际保存字符串的char类型数组free表示buf[]数组未使用字节的数量len表示buf[]数组所保存的字符串长度,并且SDS会以\0结尾,\0在Redis实现中仅作为字符串的定界符。

Redis为什么要这样设计呢?

效率高:

工作中使用Redis,经常会通过strlen命令得到一个字符串的长度,在 SDS结构中len属性记录了字符串的长度,所以我们获取一个字符串长度直接取len的值,复杂度是O(1)

而如果用C字符串,在获取一个字符串长度时,需对整个字符串进行遍历,直至遍历到空格符结束(C中遇到空格符代表一个完整字符串),此时的复杂度是O(N)

高并发场景下频繁遍历字符串,获取字符串的长度很有可能成为redis的性能瓶颈,所以SDS性能更好一些

防止数据溢出:

C字符串是不记录自身长度的相邻的两个字符串存储的方式可能是挨着的为字符串分配了合适的内存空间。如果我想更改字符串,改长了的话,没办法放下只能侵占相邻字符串的空间,自身数据溢出导致其他字符串的内容被修改。

//原始字符串:
从未止步\0从未止步\0
//自身数据溢出
从未止步\0未止步\0

而SDS很好的规避了这点,当我们需要修改数据时,首先会检查当前SDS空间len是否满足,不满足则自动扩容空间至修改所需的大小,然后再执行修改

空间预分配:

空间预分配策略用于优化SDS字符串增长操作,当修改字符串并需对SDS的空间进行扩展时,不仅会为SDS分配修改所必要的空间,还会为SDS分配额外的未使用空间free,下次再修改就先检查未使用空间free是否满足,满足则不用在扩展空间。

通过空间预分配策略,Redis可以有效的减少字符串连续增长操作,所产生的内存重分配次数

额外分配未使用空间 free 的规则:

如果对 SDS 字符串修改后,len值小于 1M,那么此时额外分配未使用空间 free 的大小与 len相等

如果对 SDS 字符串修改后,len值大于等于 1M,那么此时额外分配未使用空间 free 的大小为 1M

惰性空间释放

惰性空间释放策略则用于优化SDS字符串缩短操作,当缩短SDS字符串后,并不会立即执行内存重分配来回收多余的空间,而是用 free属性将这些空间记录下来,因此在redis中,修改字符串是一个很常见的操作,因此如果后续有增长操作,则可直接使用。

//后面的0不会被立即回收,而是使用free属性记录下来
从未止步\00
//增长字符串---直接使用0的那个空间
从未不止步\0

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

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

相关文章

pip 安装出现报错 SSLError(SSLError(“bad handshake

即使设置了清华源: pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simplepip 安装包不能配置清华源,出现报错: Retrying (Retry(total2, connectNone, readNone, redirectNone, statusNone)) after connection broken by ‘SSLE…

redis为什么用单线程模型

redis为什么用单线程模型? 最近在深入研究redis,发现其中很多值得我们借鉴的思想,实现原理等,坚持每天学习一点点,不久就可成大佬,大家加油! 言归正传,我来回答今天的问题&#xff…

[Python] 如何在Windows下安装图形可视化工具graphviz

什么是graphviz? Graphviz是一款开源的图形可视化工具,用于生成各种结构化数据的图形表示。它支持多种图形排列算法,可以将复杂的数据关系用图形的方式直观地展示出来。Graphviz广泛应用于软件工程、数据可视化、计算机网络以及其他领域的可视化分析中…

14 STM32标准库函数 之 实时时钟(RTC) 所有函数的介绍及使用

14 STM32标准库函数 之 实时时钟(RTC) 所有函数的介绍及使用 1 RTC的库函数预览1.1 函数RTC_ITConfig1.2 函数RTC_EnterConfigMode1.3 函数RTC_ExitConfigMode1.4 函数RTC_GetCounter1.5 函数RTC_SetCounter1.6 函数RTC_SetPrescaler1.7 函数RTC_ SetAla…

springboot131企业oa管理系统

企业OA管理系统 摘要 随着信息技术在管理上越来越深入而广泛的应用,管理信息系统的实施在技术上已逐步成熟。本文介绍了企业OA管理系统的开发全过程。通过分析企业OA管理系统管理的不足,创建了一个计算机管理企业OA管理系统的方案。文章介绍了企业OA管…

android 自定义键盘长按弹窗

自己记忆,下次不用找KeyboardView的onLongPress是长按监听,通过onLongPress可以获取键盘上用户长按的字母override fun onLongPress(popupKey: Keyboard.Key): Boolean {val label popupKey.labelif (!TextUtils.isEmpty(label) && popupKey.codes.get(0) ! MyKeyCode…

字符串相关的函数和内存块相关函数

𝙉𝙞𝙘𝙚!!👏🏻‧✧̣̥̇‧✦👏🏻‧✧̣̥̇‧✦ 👏🏻‧✧̣̥̇:Solitary-walk ⸝⋆ ━━━┓ - 个性标签 - :来于“云”的“羽球人”。…

python第五节:集合set(1)

集合是一个无序不重复元素的集合。集合中元素包含在花括号中,例如{a,1,tom,"xy"} 创建集合: 例子1: # set1 {a,1,tom,"xy"}set1 set()set2 set([])set3 set({})# 虽然集合用{}包含集合的元素,但是{}创…

前端开发有没有必要转鸿蒙开发?

前端开发有没有必要转鸿蒙开发?如果后面的工作中有参与鸿蒙开发的机会,那肯定是转呀!毕竟多接触一些技能也不会有什么坏处。 我想说的是:鸿蒙替代不了前端,如果你目前正在从事前端开发,那么你完全可以将鸿蒙…

springboot 整合 ElasticSearch 方法 (二)

依赖 在pom.xml文件中需要引入3个依赖, 三个都必须有并且三个依赖的版本要一致, 不然会报错. 不一定是 7.6.1 这个版本 , 只需要保证这三个依赖的版本一致就可以了. <dependency><groupId>org.elasticsearch</groupId><artifactId>elasticsearch<…

【C++入门到精通】特殊类的设计 |只能在堆 ( 栈 ) 上创建对象的类 |禁止拷贝和继承的类 [ C++入门 ]

阅读导航 引言一、特殊类 --- 不能被拷贝的类1. C98方式&#xff1a;2. C11方式&#xff1a; 二、特殊类 --- 只能在堆上创建对象的类三、特殊类 --- 只能在栈上创建对象的类四、特殊类 --- 不能被继承的类1. C98方式2. C11方法 总结温馨提示 引言 在面向对象编程中&#xff0…

制作 MSK Connect 的 Confluent Avro Converter + Debezium MySQL Connector 插件包

MSK Connect 的插件包需要将各种插件的 Jar 包及其依赖包放到一起,打成 Zip 包,上传到 S3,然后在MSK Console 上创建插件时指定好 Zip 位置即可。为了便于维护,我们不建议将各种插件的 Jar 包混在一起放入同一个文件内,最好还是按插件原来的名称单独创建文件夹,单独放置各…

Django框架(一)安装与创建项目

认识 Django Django是一个高级Python Web框架&#xff0c;它鼓励快速开发和简洁、实用的设计。它由经验丰富的开发人员构建&#xff0c;解决了Web开发的大部分麻烦&#xff0c;因此您可以专注于编写应用程序&#xff0c;而无需重新发明轮子。它是免费和开源的。 Django官网地…

react hooks 的useState:

React 的 useState Hook 是一种用于在函数组件中管理状态的机制。它可以让函数组件具有类似于类组件的状态管理能力。 useState Hook 接收一个初始值作为参数&#xff0c;并返回一个包含状态值和更新状态值的数组。 import { useState } from react;const [state, setState] …

面试经典150题(93-95)

leetcode 150道题 计划花两个月时候刷完&#xff0c;今天&#xff08;第五十三天&#xff09;完成了3道(93-95)150&#xff1a; 93.&#xff08;53. 最大子数组和&#xff09;题目描述&#xff1a; 给你一个整数数组 nums &#xff0c;请你找出一个具有最大和的连续子数组&am…

ElasticSearch常用搜索语句与SQL对比

在当今的大数据时代&#xff0c;搜索引擎成为了我们获取信息的重要工具。而ElasticSearch作为一个强大的开源搜索引擎&#xff0c;提供了丰富的搜索功能。下面&#xff0c;我们将介绍ElasticSearch中的一些常用搜索语句&#xff0c;并通过与SQL的对比来帮助大家更好地理解。 1…

代码随想录算法训练营第16天(二叉树4)| 平衡二叉树二叉树的所有路径左叶子之和

110.平衡二叉树 leetcode题目链接 题目链接/文章讲解/视频讲解 重点&#xff1a; 平衡二叉树的概念&#xff1a;所以左子树与右子树的高度差不大于1 使用后序遍历&#xff1a;手机子树的高度&#xff0c;上交给父节点&#xff0c;来计算 代码实现 class Solution { public…

Java笔记 --- 五、File

五、File 概述 将字符串变成File对象&#xff0c;再去使用里面的方法 父级路径&#xff1a;除了文件本身的路径 C:\Users\Desktop 子级路径&#xff1a;文件名 m.txt 常见的成员方法 判断、返回 length 只能获取文件的大小(字节数量) 创建、删除 delete方法默认只能删除…

行测-资料:1. 速算技巧、基期与现期

1、速算技巧 1.1 截位直除 1.1.1 截位 1.1.2 截谁 1.1.3 截几位 选项差距大&#xff1a; 四个选项首位均不同首位相同&#xff0c;第二位差大于首位 选项差距小&#xff1a; 首位相同且第二位差小于等于首位 例子 C&#xff0c;截两位。 C&#xff0c;截两位。 B&#xff0c;截…

JS中的try...catch

一、定义和结构 作用&#xff1a;捕获同步执行代码下的异常错误 在没有使用try...catch的情况下&#xff0c;同步代码执行遇到异常会报错&#xff0c;并中断后续代码执行&#xff1b; 在使用try...catch的情况下&#xff0c;同步代码执行遇到异常会抛出异常&#xff0c;并继续…