redis面试(一)String底层剖析

前言

今天开始更新一些redis相关的知识点,初步计划是redis的数据类型,以及redis分布式锁
本章节主要是redis的String类型

字符串SDS

一般情况下我们认为的redis 字符串就是String,但是我这边要说的是底层String类型。

redis底层是C语言,但是C语言中的String有一定的缺陷,所以redis开发了一个自己的字符串类型 SDS 也就是simple dynaic string,专门的数据结构,保证字符串的完整性 动态字符串

c语言中的字符串是 r,e,d,i,s,\0 这种n+1的形式存储的,读取的时候一个个的读取,一直到 \0 这个数据
获取字符串长度的时候,还要遍历一遍

redis sds的字符串类型如下

struct sdshdr {int len;	// 已使用字节数= 字符串长度int free; 	// 未使用字节数char buf[];	// 字符串本身内容
}

比如:
sdshdr
free=0
len=5
buf-> [r,e,d,i,s,\0]

c字符串里规定除了末尾可以有一个\0空字符以外,内容里不能包含空字符,否则读到空字符就认定这个字符串结束了,所以导致c字符串只能保存文本,不能保存图片和音视频一类的二进制数据

二进制问题

re\0di\0s
re di s
如果你要是在内容里包含了很多空字符的话,你就不是二进制安全的了
但是sds实现了二进制安全,而且允许内容里包含\0,这是为什么呢,因为sds里有一个len,他是根据len来读取指定字节数量的字符的,而不是根据\0来判断字符串是否结束了,这是一个很关键的优化,通过这个就可以实现二进制安全了
但是redis还是遵守了末位是\0的c规范,这样保存的字符串,就可以复用c语言的一些函数了,因为c语言函数是这么规定的

c语言原生字符串,strlen,获取字符串长度,遍历,O(n),二进制不安全的,对于二进制数据来说,图片、视频、音频、压缩文件,这种数据都是以一大堆的二进制串来存储的,里面肯定会有很多\0空字符,对于c语言来说,读取的时候,一定要按照\0来截断,肯定不行的

二进制不安全,原生的c语言字符串没法安全的存储二进制数据

redis里面的sds,他里面有两个关键的字段,len和free,buf = [] 跟c语言没太大差别,len和free很厉害,free的作用,我们还没讲,len有2个作用,直接读取len,strlen,O(1),读取buf里的数据,不是遍历看到\0就停止

根据len读取指定字节数量的buf数字的内容,形成一个完整的内容,对于我们来说,redis里的sds存储二进制的数据,图片、音视频,就算buf里包含了很多\0空字符,根据len来读取,不是根据\0来截断,redis sds可以实现二进制安全性,安全的保存二进制数据

避免缓冲区溢出

redis和spark两个字符串,在内存地址里,连续的存储在了一起
[r,e,d,i,s,\0,s,p,a,r,k,\0]

str = redis

strcat(str, sentinel) -> 插入忘记了给sentinel字符串分配内存空间

c语言原生字符串可能搞出缓冲区溢出的问题,那就是说,r,e,d,i,s,s,p,a,r,k,连续两个字符串,redis和spark,结果我们要是用c语言的strcat函数,搞了一个strcat(str, ‘sentinel’),想要把sentinel拼接到redis字符串后面去,又忘了给sentinel提前分配内存空间,就会导致,r,e,d,i,s,s,e,n,t,i,n,e,l,直接覆盖掉spark了,这就是缓冲区溢出
[r,e,d,i,s,\0,s,e,n,t,i,n,e,l,\0]

sds(free=0,len=5,buf[r,e,d,i,s,\0]) -> sds(free=13,len=13,buf[r,e,d,i,s,s,e,n,t,i,n,e,l,\0])

sds会自动检查字符串扩容空间是否足够,不够就扩容空间,扩容完毕了再修改字符串的内容,比如sdscat就是这样的拼接字符串的函数,比如一开始sds的free=0,len=5,buf=redis,但是现在你要扩容加上sentinel了,此时就会先扩容,free=13,len=13,buf=redissentinel

内存预分配

除了扩容,他还会额外的给13个自己的free空间

c字符串在拼接或者截断的时候,要不然就得扩容数组,要不然就是释放空间内存,就是有频繁的内存重分配动作,这个内存重分配是很耗费时间的,涉及到os系统调用,redis频繁修改字符串,频繁内存重分配,那就真的是很尴尬

sds为了避免这种频繁内存重分配的问题,才设计了free,这个free可以实现内存预分配和惰性释放,每次sds的内存空间要进行扩容的时候,扩容完毕后,都会根据一个公式,提前计算出free,预分配一定的内存空间出来

扩容后,sds长度小于1mb,就把free设置为跟len一样,做一个双倍预分配,如果扩容后len大于1mb了,就把free设置为1mb就可以了,毕竟不能无限制的扩容下去,这个预分配后,就是底层c里的数组,留了一定字节数量的空间,但是没有真正使用

这样你后续再修改字符串,直接就用free空间就可以了,避免了频繁重分配内存了

惰性释放

如果缩短一个字符串,那么就会把字符串正常缩短,然后len设置为字符串长度,free就是原长度-现长度,以后如果要增长,还可以用free,如果确实要释放内存空间,sds提供了api来释放,但是他是不会立即释放掉的。而是在过一段时间之后,发现空间不足了,才会释放掉这部分空间

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

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

相关文章

RK3588+MIPI+GMSL+AI摄像机:自动车载4/8通道GMSL采集/边缘计算盒解决方案

RK3588作为目前市面能买到的最强国产SOC,有强大的硬件配置。在智能汽车飞速发展,对图像数据矿场要求越来越多的环境下,如何高效采集数据,或者运行AI应用,成为刚需。 推出的4/8通道GMSL采集/边缘计算盒产品满足这些需求…

Spring验证码

前言:使用Hutool 1.什么是Hutool? 2.代码复制到test类中 3.代码爆红,说明需要引入依赖 4.根据名取Maven仓库相关依赖 5.在pom.xml文件中进行配置 6.引入成功 7. 运行程序 打开d盘,发现已经生成了验证码的图片,路径在…

Codeforces Round 654 (Div. 2) C. A Cookie for You (模拟)

我认为这道题就是个脑筋急转弯。 首先我们知道当a b < n m的时候&#xff0c;饼干总数都不够人的总数&#xff0c;那肯定是NO。 并且注意题干&#xff0c;我们可以得知当a b的时候&#xff0c;第一类和第二类人可以任意选两种饼干中的一种。 之后我们可以分类讨论一下。 …

网格布局 HTML CSS grid layout demo

文章目录 页面效果代码 (HTML CSS)参考 页面效果 代码 (HTML CSS) <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"…

[ BLE4.0 ] 伦茨ST17H66开发-串口UART0的接收与发送

目录 一、前言 二、实现步骤 1.设置回调函数 2.关闭睡眠模式 三、效果展示 四、工程源代码 一、前言 串口通信在任何一款单片机开发中都是尤为重要的。本文涉及的开发所使用的例程依然是基于[ BLE4.0 ] 伦茨ST17H66开发-OSAL系统中添加自己的Task任务文章的工程源码&#x…

windows@powershell@任务计划@自动任务计划@taskschd.msc.md

文章目录 使用任务计划windows中的任务计划任务计划命令行程序开发windows 应用中相关api传统图形界面FAQ schtasks 命令常见用法创建计划任务删除计划任务查询计划任务修改计划任务运行计划任务 PowerShell ScheduledTasks常用 cmdlet 简介1. Get-ScheduledTask2. Register-Sc…

Git远程仓库推送

这里我只连接了两个站点的远程仓库&#xff0c;一个是国内的Gitee&#xff0c;另一个是Github&#xff0c;这两个站点的连接方式主要有两种&#xff0c;第一种就是通过https来连接远程仓库&#xff0c;另一种是通过ssh公钥来连接&#xff0c;这两个站点练接的大致过程都是一样的…

我出一道面试题,看看你能拿 3k 还是 30k!

大家好&#xff0c;我是程序员鱼皮。欢迎屏幕前的各位来到今天的模拟面试现场&#xff0c;接下来我会出一道经典的后端面试题&#xff0c;你只需要进行 4 个简单的选择&#xff0c;就能判断出来你的水平是新手&#xff08;3k&#xff09;、初级&#xff08;10k&#xff09;、中…

4 款最佳 C# 无头浏览器

摘要&#xff1a; 在当今大数据时代&#xff0c;高效的数据采集成为众多项目的关键一环。对于偏好C#语言的开发者而言&#xff0c;无头浏览器是实现网页自动化交互、数据抓取的强大工具。本文将深入探讨四款顶尖的C#无头浏览器库&#xff0c;分析它们的特性和应用场景&#xf…

怎么把C盘分成两个盘?让C盘分区更简单,赶快试试!

在日常使用电脑的过程中&#xff0c;有时我们可能希望将C盘分割成两个独立的分区&#xff0c;以便更好地管理文件和数据。这种操作需要谨慎进行&#xff0c;因为错误的分区操作可能导致数据丢失。那么&#xff0c;我们该怎么把C盘分成两个盘呢&#xff1f;下面&#xff0c;我将…

lua 游戏架构 之 游戏 AI (六)ai_auto_skill

定义一个为ai_auto_skill的类&#xff0c;继承自ai_base类。ai_auto_skill类的目的是在AI自动战斗模式下&#xff0c;根据配置和条件自动选择并使用技能。 lua 游戏架构 之 游戏 AI &#xff08;一&#xff09;ai_base-CSDN博客文章浏览阅读379次。定义了一套接口和属性&#…

vue3在元素上绑定自定义事件弹出虚拟键盘

最近开发中遇到一个需求: 焊接机器人的屏幕上集成web前端网页, 但是没有接入键盘。这就需要web端开发一个虚拟键盘,在网上找个很多虚拟键盘没有特别适合,索性自己写个简单的 图片: 代码: (代码可能比较垃圾冗余,也没时间优化,凑合看吧) 第一步:创建键盘组件 为了方便使用…

3.2.微调

微调 ​ 对于一些样本数量有限的数据集&#xff0c;如果使用较大的模型&#xff0c;可能很快过拟合&#xff0c;较小的模型可能效果不好。这个问题的一个解决方案是收集更多数据&#xff0c;但其实在很多情况下这是很难做到的。 ​ 另一种方法就是迁移学习(transfer learning…

c++如何理解多态与虚函数

目录 **前言****1. 何为多态**1.1 **编译时多态**1.1.1 函数重载1.1.2 模板 **1.2 运行时多态****1.2.1 虚函数****1.2.2 为什么要用父类指针去调用子类函数** **2. 注意****2.1 基类的析构函数应写为虚函数****2.2 构造函数不能设为虚函数** **本文参考** 前言 在学习 c 的虚…

打造重庆市数字化教育“新名片”,广阳湾珊瑚中学凭实力“出圈”!

分布于教学楼连廊顶部的智能照明设备,根据不同的时间和场景需求自动调节灯光亮度和开关状态;安装于各个教室内的智能黑板、学校同步时钟、学生互动设备,在极简以太全光网的赋能下,为师生提供丰富的教学体验与学习支持......行走于重庆市广阳湾珊瑚中学,像是与充满科技感的“校园…

病理AI领域的基础模型汇总|顶刊专题汇总·24-07-26

小罗碎碎念 本期文献主题&#xff1a;病理AI领域的最新基础模型 今天的推文是一期生日特辑&#xff0c;定时在下午六点二十一分发表&#xff08;今天农历六月二十一&#xff0c;哈哈&#xff09;&#xff0c;算是自己给自己的24岁生日礼物&#xff0c;希望24岁这一年&#xff0…

ollama本地部署大语言模型记录

目录 安装Ollama更改模型存放位置 拉取模型GemmaMistralQwen1.5(通义千问)codellama 部署Open webui测试性能知识广度问题1问题2 代码能力总结 最近突然对大语言模型感兴趣 同时在平时的一些线下断网的CTF比赛中&#xff0c;大语言模型也可以作为一个能对话交互的高级知识检索…

SSRF中伪协议学习

SSRF常用的伪协议 file:// 从文件系统中获取文件内容,如file:///etc/passwd dict:// 字典服务协议,访问字典资源,如 dict:///ip:6739/info: ftp:// 可用于网络端口扫描 sftp:// SSH文件传输协议或安全文件传输协议 ldap://轻量级目录访问协议 tftp:// 简单文件传输协议 gopher…

【JavaScript】函数声明和函数表达式的区别

文章目录 一、函数声明1. 定义方式2. 作用域提升&#xff08;Hoisting&#xff09;3. 块级作用域 二、函数表达式1. 定义方式2. 作用域提升&#xff08;Hoisting&#xff09;3. 自引用 三、其他区别1. 函数名2. 可读性和代码组织3. 使用场景 四、总结函数声明函数表达式 在Java…

【大模型系列】Video-LaVIT(2024.06)

Paper&#xff1a;https://arxiv.org/abs/2402.03161Github&#xff1a;https://video-lavit.github.io/Title&#xff1a;Video-LaVIT: Unified Video-Language Pre-training with Decoupled Visual-Motional TokenizationAuthor&#xff1a;Yang Jin&#xff0c; 北大&#x…