Redis (String 底层数据结构)

Redis是查询数据很快的no Sql数据库。其原因不只是因为它存储在内存中,还因为它存储各种类型的数据结构。比如这期说到的String类型。String类型在Redis中应用很广泛。Redis中存储数据是以键值对的方式。这个键都是String类型。所以下面我们看下String类型的底层数据结构吧。

1. 简单字符串(SDS)

1.1Redis是由C语言开发的。为啥字符串没有使用C字符串呢?

  1. 这是因为C字符串是以\0为结尾。所以保存的字符串长度总是比原字符串长1。而且存储的特殊字符也可能由于\0得特性导致数据丢失。如果Redis想要存储文件数据则就不能使用C字符串。否则会导致数据丢失。
  2. C字符串是以char[]数组来实现的,在创建出来之后就不能改变其长度了,所以如果执行字符串拼接或者字符串截取就需要创建新的char[]数组。这样就就会徒增性能的消耗。

1.2 Redis 字符串实现

Redis使用SDS来实现。

1.2.1 SDS结构
struct sdshdr {//记录buf数组中已使用字节的数量//等于SDS所保存字符串的长度int len;//记录buf数组中未使用字节的数量int free;//字节数组,用于保存字符串char buf[];
};

在这里插入图片描述
  Redis虽然还是以\0为结尾但是不会再遇到\0就认为字符串到头了。这样做的好处还可以使用C语言中一些操作字符串的方法。

1.2.2 获取字符串长度

  C字符串需要判断\0的位置,所以计算长度是O(n)。而SDS有len字段可以直接判断字符串长度。所以是O(n)。

1.2.3 杜绝缓冲区溢出
  1. C语言字符串如果需要把一个字符串后面拼接另一个字符串。因为C语言字符串没有记录字符串的长度。假定没有分配足够的内存给后面一个字符串的长度。则会导致产生缓存区溢出。
  2. SDS在进行拼接时会判断可用长度free是否可以容纳拼接字符串的长度。如果不能够容纳则会进行扩容。扩容后达到足够容纳拼接字符串的可用空间后才会继续进行拼接操作。这样就不会造成缓存区的溢出了。
1.2.4 减少修改字符串时带来的内存重分配次数
  1. 正如上面所说拼接字符串。C语言需要每次都对目标字符串进行内存重新分配。所以只要每次操作都需要进行重新分配。
  2. 为了解决上面的问题SDS实现了空间预分配和惰性空间释放两种策略。
    a. 空间预分配
    ⅰ. 对SDS进行修改后如果长度小于1MB。那么SDS就会分配和len一样长度的大小的额外空间。比如分配后的长度为13。最终的len = 13 + 13 + 1 = 27。额外的一字节用于保存空字符。
    ⅱ. 如果分配后长度大于1MB。那么SDS就会分配多1MB的额外的空间。比如分配后的长度为30MB。最终的len = 30MB + 1MB + 1字节。
    b. 惰性空间释放
    ⅰ. 如果把字符串缩短。也不会把空余出来的空间给立马释放掉。会等待字符串变长时使用。SDS也提供了响应的API。让我们可以完全释放掉free的空间。
1.2.5 二进制安全

  C字符串中的字符必须符合某种编码(比如ASCII),并且除了字符串的末尾之外,字符串里面不能包含空字符,否则最先被程序读入的空字符将被误认为是字符串结尾,这些限制使得C字符串只能保存文本数据,而不能保存像图片、音频、视频、压缩文件这样的二进制数据。
  SDS的API都是二进制安全的(binary-safe),所有SDS API都会以处理二进制的方式来处理SDS存放在buf数组里的数据,程序不会对其中的数据做任何限制、过滤、或者假设,数据在写入时是什么样的,它被读取时就是什么样。

总结

所以根据上面的几个方面我们可以看出Redis使用SDS对字符串进行了优化。保证了字符串的安全性,提高了字符串操作的性能。

参考:《Redis开发与实现》

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

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

相关文章

mac+win10虚拟机+phpstudy便捷运行php+pgsql的方法

痛点:mac下要搭建nginxphp(含pdo_pgsql)pgsql比较麻烦 另类解决方法: 前提:mac下需要已安装win10虚拟机 方法: 1. win10虚拟机下安装phpstudy8.1 -> 开启php扩展(pdo_pgsql)&a…

scRNA+bulk+MR:动脉粥样硬化五个GEO数据集+GWAS,工作量十分到位

今天给大家分享一篇JCR一区,单细胞bulkMR的文章:An integrative analysis of single-cell and bulk transcriptome and bidirectional mendelian randomization analysis identified C1Q as a novel stimulated risk gene for Atherosclerosis 标题&…

智慧驿站:智慧公厕的升级版,助力城市公共卫生设施的全面变革

智慧驿站,作为集合了智慧公厕的多功能驿站式的智慧城市部件,给城市的新基建带来了全面的变化。智慧公厕赋予智慧驿站智慧化管理的功能,将创意外观设计、智慧管理系统、全金属耐用结构和用材、整体制作与运输、快速落地使用、众多功能集合于一…

素组主元素

主要元素(主元素)是在一整数序列(长度是N)中出现次数大于N/2的元素,因为整数序列本身长度就是N,那么只要该整数序列中存在主元素,主要元素就是唯一的 思路: 思路一:穷举…

从PDF到高清图片:一步步学习如何转换PDF文件为高清图片

引言 PDF文件是一种便携式文档格式(Portable Document Format),最初由Adobe Systems开发,用于在不同操作系统和软件之间保持文档格式的一致性。PDF文件通常包含文本、图片、图形等多种元素,并且可以以高度压缩的方式存…

如何在Linux系统运行RStudio Server并实现无公网IP远程访问【内网穿透】

文章目录 推荐 前言1. 安装RStudio Server2. 本地访问3. Linux 安装cpolar4. 配置RStudio server公网访问地址5. 公网远程访问RStudio6. 固定RStudio公网地址 推荐 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下…

电视盒子什么牌子好?经销商分享2024电视盒子排行榜

店内的消费者们在买电视盒子的时候会问我电视盒子什么牌子好,面对众多品牌和产品电视盒子究竟应该如何和选择呢?我整理了店内的销量情况,花费一周时间总结了线下热销的电视盒子排行榜,不知道如何挑选电视盒子的朋友们可以关注起来…

总结UDP协议各类知识点

前言 本篇博客博主将详细地介绍UDP有关知识点,坐好板凳发车啦~ 一.UDP特点 1.无连接 UDP传输的过程类似于发短信,知道对端的IP和端口号就直接进行传输,不需要建立连接; 2.不可靠传输 没有任何的安全机制,发送端发…

vscode上编辑vba

安装xvba插件更换vscode的工作目录启动扩展服务器在config.json中添加目标工作簿的名称加载excel文件(必须带宏的xlsm)这个扩展就会自动提取出Excel文件中的代码Export VBA(编辑完成的VBA代码保存到 Excel文件 )再打开excel文件可…

Node.js-------初识Node.js与内置模块

能够知道什么是 Node.js能够知道 Node.js 可以做什么能够说出 Node.js 中的 JavaScript 的组成部分能够使用 fs 模块读写操作文件能够使用 path 模块处理路径能够使用 http 模块写一个基本的 web 服务器 一.初识Node.js 1.浏览器中的 JavaScript 的组成部分 2.Node.js 简介 …

时序数据库IoTDB:功能详解与行业应用

一文读懂时序数据库 IoTDB。 01 为什么需要时序数据库 解释时序数据库前,先了解一下何谓时序数据。 时序数据,也称为时间序列数据,是指按时间顺序记录的同一统计指标的数据集合。这类数据的来源主要是能源、工程、交通等工业物联网强关联行业…

【c++初阶】类与对象(下)

✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅ ✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨ 🌿🌿🌿🌿🌿🌿🌿🌿🌿🌿🌿🌿🌿🌿&#x1…