当前位置: 首页 > news >正文

浅谈redis之SDS

SDS

  • 什么是SDS
    • SDS结构
      • len的作用
      • free的作用
      • buf的作用
        • 简单示例
    • SDS机制
      • 重新分配内存
        • 分配内存机制
          • 小于1MB情况
          • 大于1MB情况
          • 为什么这样分配
      • 惰性释放内存

什么是SDS

SDS:全名 simple dynamic string,意为简单动态字符串,作为redis里的一种数据结构,它有着普通C字符所不具备的一些特点.

SDS结构

struct sdshdr {int len;int free;char buf[];
}
len 意指SDS所保存字符的长度
free 则指buf数组中未使用字节的数量
buf 字节数组,用于保存字符串

从结构设计上,我们可以对 SDS的设计的优点可窥一二

len的作用

首先从len开始,为什么SDS会记录一个len值,熟悉遍历大法的我们知道,要想知道一个字符串的长度,最原始的办法是从首位数到末位,假如我们有一个长度为n的字符串,在未记录其长度时,我们要想知道其len值,需要话费的时间会是O(N),如果我们是使用的SDS记录的字符串,则花费时间使用STRLENO(1),花费的时间越少,意味着性能越高.

free的作用

free,意指buf数组还有多少空间是未使用,这个值一般用在buf空间扩展,以及添加新值时会用到。不同于C字符串的扩张,SDS API在对SDS进行修改时,会先检查SDS的空间是否满足所需需求,若不满足,API会自动将SDS的大小扩展至所需空间.这样做的好处是不会有缓冲区的溢出.

buf的作用

SDS的API都是二进制安全(binary-safe)的,通俗的来说SDS的API通过某种机制,保证了读写字符串的时候不会损害其内容,因为在C语言中,“\0”表示了字符串的结束,出现这个字符,字符串就会被截断,造成错误的字符,而在sds中即使字符串里有“\0”,也不会被截断,除非是redis自己的结尾字符,保证了读写的一致性.虽然SDS是二进制安全的,但是它还是兼容了一部分C字符的特性.

简单示例

现在我们,往SDS保存madpudding,按照上述结构,存入字符的SDS的长度是10,而buf里的前10个字节分别保存madpudding 10个字符串.实际上buf里会有11个字符,sds还是会以\0,作为字符结尾.

SDS机制

重新分配内存

分配内存机制
小于1MB情况

如果对sds进行修改后,整体的长度小于1MB,那么redis分配的是和len属性同样的大小空间,以madpudding为例,是10(buf长度)+10(free空间)+1(结尾字符).

大于1MB情况

假如修改后整体长度大于20MB,则实际空间是20MB(buf长度)+1MB(free空间)+1(结尾字符).

为什么这样分配

为什么redis会为sds这样分配空间呢?假设在实际使用中,有个sds一直在增加,按上述分配法,则在n次扩展中,sds最多重新分配n次空间,要知道io是很消耗性能的,最多n次n次,性能差距是非常大的.

惰性释放内存

假如sds的字符,一直在减少,那么sds会立马释放未使用的空间嘛?答案是否定的,sds只会在free中依次记录,等待将来使用。这样做的目的是避免了缩减字符而重新释放内存,并为将来可能有的增长提供了空间基础.当然sds提供了真正需要释放空间的命令,让开发者不用担心惰性释放造成空间浪费.

相关文章:

  • 宝物筛选(二进制优化多重背包)
  • 数据结构与算法:图形数据结构
  • 解决弹性布局父元素设置高自动换行,子元素均分高度问题(align-content: flex-start)
  • 【思路】短链生成及访问
  • vivo 基于 StarRocks 构建实时大数据分析平台,为业务搭建数据桥梁
  • 获取视频第一帧,以及后续上传
  • Zabbix 6.2.1 安装
  • Jenkins解决Host key verification failed (2)
  • RandAugment(NeurIPS 2020)论文速读
  • C++学习规划“的 PPT 大纲设计
  • sql注入 [极客大挑战 2019]FinalSQL1
  • hbuilderx创建、运行uni-app
  • B树的介绍
  • xxl-job架构原理讲解
  • 剑指offer面试题18 树的子结构
  • [译]CSS 居中(Center)方法大合集
  • 【跃迁之路】【444天】程序员高效学习方法论探索系列(实验阶段201-2018.04.25)...
  • Android Studio:GIT提交项目到远程仓库
  • CSS3 变换
  • IIS 10 PHP CGI 设置 PHP_INI_SCAN_DIR
  • java第三方包学习之lombok
  • Java读取Properties文件的六种方法
  • MaxCompute访问TableStore(OTS) 数据
  • Nodejs和JavaWeb协助开发
  • Redis学习笔记 - pipline(流水线、管道)
  • ucore操作系统实验笔记 - 重新理解中断
  • 从零开始在ubuntu上搭建node开发环境
  • 工程优化暨babel升级小记
  • 技术发展面试
  • 近期前端发展计划
  • 聊聊springcloud的EurekaClientAutoConfiguration
  • 前嗅ForeSpider采集配置界面介绍
  • 树莓派 - 使用须知
  • ​​​​​​​GitLab 之 GitLab-Runner 安装,配置与问题汇总
  • #经典论文 异质山坡的物理模型 2 有效导水率
  • #我与Java虚拟机的故事#连载02:“小蓝”陪伴的日日夜夜
  • $(document).ready(function(){}), $().ready(function(){})和$(function(){})三者区别
  • (2)STM32单片机上位机
  • (Mac上)使用Python进行matplotlib 画图时,中文显示不出来
  • (附源码)ssm教材管理系统 毕业设计 011229
  • (一)spring cloud微服务分布式云架构 - Spring Cloud简介
  • (转)关于pipe()的详细解析
  • 、写入Shellcode到注册表上线
  • .bat批处理(十一):替换字符串中包含百分号%的子串
  • .NET 发展历程
  • .NET 应用启用与禁用自动生成绑定重定向 (bindingRedirect),解决不同版本 dll 的依赖问题
  • .NetCore 如何动态路由
  • ??在JSP中,java和JavaScript如何交互?
  • [ NOI 2001 ] 食物链
  • [100天算法】-x 的平方根(day 61)
  • [23] 4K4D: Real-Time 4D View Synthesis at 4K Resolution
  • [Android 数据通信] android cmwap接入点
  • [Angular] 笔记 20:NgContent
  • [CentOs7]iptables防火墙安装与设置
  • [CISCN 2019华东南]Web11