Redis的字符串是怎么实现的

news2024/12/24 13:01:17

本篇会讲以下内容:

  • Redis字符串的实现

  • Redis字符串的性能优势

Redis字符串的实现

Redis虽然是用C语言写的,但却没有直接用C语言的字符串,而是自己实现了一套字符串。目的就是为了提升速度,提升性能,可以看出Redis为了高性能也是煞费苦心。

Redis构建了一个叫做简单动态字符串(Simple Dynamic String),简称SDS

1.SDS 代码结构

struct sdshdr{
    //  记录已使用长度
    int len;
    // 记录空闲未使用的长度
    int free;
    // 字符数组
    char[] buf;
};

SDS ?什么鬼?可能对此陌生的朋友对这个名称有疑惑。只是个名词而已不必在意,我们要重点欣赏借鉴Redis的设计思路。下面画个图来说明,一目了然。

Redis的字符串也会遵守C语言的字符串的实现规则,即最后一个字符为空字符。然而这个空字符不会被计算在len里头。

2.SDS 动态扩展特点

SDS的最厉害最奇妙之处在于它的Dynamic。动态变化长度。举个例子

如上图所示刚开始s1 只有5个空闲位子,后面需要追加' world' 6个字符,很明显是不够的。那咋办?Redis会做以下三个操作:

  1. 计算出大小是否足够

  2. 开辟空间至满足所需大小

  3. 开辟与已使用大小len相同长度的空闲free空间(如果len < 1M)开辟1M长度的空闲free空间(如果len >= 1M)

看到这儿为止有没有朋友觉得这个实现跟Java的列表List实现有点类似呢?看完后面的会觉得更像了。

Redis字符串的性能优势

  • 快速获取字符串长度

  • 避免缓冲区溢出

  • 降低空间分配次数提升内存使用效率

1.快速获取字符串长度

再看下上面的SDS结构体:

struct sdshdr{
    //  记录已使用长度
    int len;
    // 记录空闲未使用的长度
    int free;
    // 字符数组
    char[] buf;
};

由于在SDS里存了已使用字符长度len,所以当想获取字符串长度时直接返回len即可,时间复杂度为O(1)。如果使用C语言的字符串的话它的字符串长度获取函数时间复杂度为O(n),n为字符个数,因为他是从头到尾(到空字符'\0')遍历相加。

2.避免缓冲区溢出

对一个C语言字符串进行strcat追加字符串的时候需要提前开辟需要的空间,如果不开辟空间的话可能会造成缓冲区溢出,而影响程序其他代码。如下图,有一个字符串s1="hello" 和 字符串s2="baby",现在要执行strcat(s1,"world"),并且执行前未给s1开辟空间,所以造成了缓冲区溢出。

而对于Redis而言由于每次追加字符串时都会检查空间是否够用,所以不会存在缓冲区溢出问题。每次追加操作前都会做如下操作:

  1. 计算出大小是否足够

  2. 开辟空间至满足所需大小

3.降低空间分配次数提升内存使用效率

字符串的追加操作会涉及到内存分配问题,然而内存分配问题会牵扯内存划分算法以及系统调用所以如果频繁发生的话影响性能,所以对于性能至上的Redis来说这是万万不能忍受的。所以采取了以下两种优化措施

  • 空间与分配

  • 惰性空间回收

1. 空间预分配

对于追加操作来说,Redis不仅会开辟空间至够用而且还会预分配未使用的空间(free)来用于下一次操作。至于未使用的空间(free)的大小则由修改后的字符串长度决定。

当修改后的字符串长度len < 1M,则会分配与len相同长度的未使用的空间(free)

当修改后的字符串长度len >= 1M,则会分配1M长度的未使用的空间(free)

有了这个预分配策略之后会减少内存分配次数,因为分配之前会检查已有的free空间是否够,如果够则不开辟了~

2. 惰性空间回收

与上面情况相反,惰性空间回收适用于字符串缩减操作。比如有个字符串s1="hello world",对s1进行sdstrim(s1," world")操作,执行完该操作之后Redis不会立即回收减少的部分,而是会分配给下一个需要内存的程序。当然,Redis也提供了回收内存的api,可以自己手动调用来回收缩减部分的内存。

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

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

相关文章

Nacos的服务注册之客户端

服务注册到Nacos以后,会保存在一个本地注册表中,这个注册表是一个map. private Map<String, Map<String, Service>> serviceMap new ConcurrentHashMap<>(); key是namespace,用来隔离环境 value又是一个map      key是group      value又是一个s…

java计算机毕业设计springboot+vue远程教育系统

项目介绍 通篇文章的撰写基础是实际的应用需要,然后在架构系统之前全面复习大学所修习的相关知识以及网络提供的技术应用教程,以远程教育系统的实际应用需要出发,架构系统来改善现远程教育系统工作流程繁琐等问题。不仅如此以操作者的角度来说,该系统的架构能够对多媒体课程进…

以太网 DHCP(简介、DHCP工作原理、租期时间)

2.13.0 以太网 DHCP&#xff08;简介、DHCP工作原理、租期时间&#xff09; DHCP的作用&#xff1a;企业网络中存在大量的终端设备&#xff08;PC&#xff09;&#xff0c;管理员配置设备上网参数工作量大&#xff0c;而且效率不高&#xff0c;手动配置容易出错&#xff0c;DH…

数据库复杂sql如何编写入手

前言&#xff1a;说到数据库我想大家都不陌生&#xff0c;对主流的数据库都会基本使用&#xff0c;但是要写好sql完成复杂的sql编写是需要对数据库原理&#xff0c;sql脚本语法有一定的了解的&#xff0c;但是对于开发人员来说&#xff0c;平常都是在curd写一些业务代码&#x…

Flutter 中使用 OpenAI GPT-3 进行语义化处理

Flutter 中使用 OpenAI GPT-3 进行语义化处理 前言 最近 openai 的 ChatGPT 火了&#xff0c;然后我也想着用它来做点什么&#xff0c;于是就写了个 调用 openai api 语言执行工具&#xff0c;跑个测试&#xff0c;以后再有功能也可以在这个程序上面试验。 copilot 也是用的 op…

m基于FPGA的64QAM调制解调、载波同步verilog实现

目录 1.算法描述 2.仿真效果预览 3.MATLAB核心程序 4.完整MATLAB 1.算法描述 64QAM&#xff08;正交幅度调制&#xff09;&#xff0c;在使用同轴电缆的网络中&#xff0c;这种数字频率调制技术通常用于发送下行链路数据。64QAM在6mhz信道中&#xff0c;64QAM的传输速率非常…

Qt编写视频监控系统(移动侦测/遮挡报警/区域入侵/越界侦测/报警输入输出等)

一、前言 得益于标准的onvif协议&#xff0c;各大监控厂商的设备都会支持onvif协议&#xff0c;在onvif协议中就包括了事件订阅机制&#xff0c;通过这个机制&#xff0c;可以拿到各种报警事件&#xff0c;比如移动侦测/遮挡报警/区域入侵/越界侦测/报警输入输出等&#xff0c…

深度学习-环境搭建(安装Pytorch)

文章目录前言一、安装Anaconda二、查看电脑显卡支持的CUDA版本三、更新CUDA版本四、创建并激活Anaconda虚拟环境需要创建虚拟环境而最好不在base下载的原因五、安装pytorchPS&#xff1a;注意事项六、下载其他库七、检查安装结果总结前言 入门深度学习过程中&#xff0c;我决定…

[附源码]JAVA毕业设计鞋店销售管理(系统+LW)

[附源码]JAVA毕业设计鞋店销售管理&#xff08;系统LW&#xff09; 项目运行 环境项配置&#xff1a; Jdk1.8 Tomcat8.5 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&…

都在说软件测试真的干不到35岁,那咋办呢...我都36了...

作为一个已经36岁但仍奋战在测试一线的老测试员&#xff0c;被人无数次问到这个问题&#xff0c;也回答过无数次&#xff0c;刚看到 程序员真的干到35岁就干不动了吗 想到&#xff0c;在测试行业&#xff0c;也有很多年轻人在焦虑这个问题。现在小编就从管理、技术、思维、体力…

Pytho——naiohttp的简单使用

1.aiohttp的简单使用(配合asyncio模块) import asyncio,aiohttpasync def fetch_async(url):print(url)async with aiohttp.request("GET",url) as r:reponse await r.text(encoding"utf-8")  #或者直接await r.read()不编码&#xff0c;直接读取&…

我不谈ChatGPT

&#xff08;1&#xff09;数据有两个未经证实的传闻&#xff1a;1、客服问答&#xff1a;80%用户问的问题都是那20%常见问题&#xff0c;但是就是这样&#xff0c;占用了客服人员80%的工作量和工作时间2、资讯搜索&#xff1a;谷歌一位员工说&#xff0c;在互联网上&#xff0…

Spring Cloud Alibaba-全面详解(学习总结---从入门到深化)

​​​​​​​ Spring Cloud Alibaba简介 什么是Spring Cloud Alibaba Spring Cloud Alibaba致力于提供微服务开发的一站式解决方案。 此项目包含开发分布式应用微服务的必需组件&#xff0c;方便开发者通过 Spring Cloud 编程模型轻松使用这些组件来开发分布式应用服务。 为…

OSI七层模型中各层网络协议

应用层: (典型设备:应用程序&#xff0c;如FTP&#xff0c;SMTP &#xff0c;HTTP) DHCP(Dynamic Host Configuration Protocol)动态主机分配协议&#xff0c;使用 UDP 协议工作&#xff0c;主要有两个用途&#xff1a;给内部网络或网络服务供应商自动分配 IP 地址&#xff0c…

spring——Spring 注入内部Bean——setter 方式注入内部 Bean

我们将定义在 <bean> 元素的 <property> 或 <constructor-arg> 元素内部的 Bean&#xff0c;称为“内部 Bean”。 项目依赖&#xff1a; <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org…

交战“低代码”,云大厂跑马圈地

者 关注 2022年末,云大厂阿里、腾讯、华为(ATH)开始了新一轮的跑马圈地。 这一次交战的战场,是低代码。 11月18日,华为AppCube全线产品全面升级,在低代码、零代码、数据看板三个方面,升级优化;11月13日,腾讯升级了云开发开发者工具“微搭”,目前已服务开发者数300万…

疫情期间,家中常备药物有哪些?这份清单请收好

【防疫科普】疫情期间&#xff0c;家中常备药物有哪些&#xff1f;这份清单请收好 为加强防疫知识科普&#xff0c;提振群众战“疫”必胜信心&#xff0c;疫情期间&#xff0c;我们将持续向广大市民朋友传递科学健康科普知识、防疫提醒、自我防护注意事项、疫情期间心理疏导等相…

Python融于ASP框架

一、ASP的平反 想到ASP 很多人会说 “asp语言很蛋疼&#xff0c;不能面向对象&#xff0c;功能单一&#xff0c;很多东西实现不了” 等等诸如此类。 以上说法都是错误的&#xff0c;其一ASp不是一种语言是 微软用来代替CGI的一种web框架&#xff0c;只不过我们一直被扭曲在 vbs…

计算机毕业设计php_thinkphp_vue的校园论坛网站

运行环境 开发语言&#xff1a;PHP 数据库:MYSQL数据库 应用服务:apache服务器 使用框架:ThinkPHP&#xff1a;vue 开发工具:VScode/Dreamweaver/PhpStorm等均可 项目简介 在各学校的校园论坛中,交流是一项非常重要的事情。随着计算机多媒体技术的发展和网络的普及。采用当前流…

Python 数据库开发实战 - Redis命令行客户端与图形客户端的简单使用

上一章节我们已经启动了 redis 服务器&#xff0c;在这一章节我们就爱你过来学习 redis命令行客户端与图形客户端的简单使用&#xff0c;以及 redis 的 一些关键参数。 Redis 命令行客户端 - redis-cli redis-cli 是 Redis 自带的 命令行终端界面&#xff0c;一个简单的程序&…