文档章节

Redis研究-1.简单动态字符串

会飞的杨先生
 会飞的杨先生
发布于 2015/08/24 11:15
字数 1044
阅读 10002
收藏 56
点赞 2
评论 7

我们知道,在C字符串中,底层的实现是使用c字符数组来实现的,但是在高性能以及内存安全方面,使用底层的c字符串是满足不了的,举个简单的例子,如果你使用strcat(s,s1)函数,如果在操作之前不判断s的空间是否能够容纳s1的内容,那么就很有可能导致内存溢出,而导致操作失败,因此,为了满足性能及内存安全方面的要求,Redis实现了SDS。

SDS的定义是(位于sds.h):

struct sdshdr {
   
    // buf 中已占用空间的长度
    int len;

    // buf 中剩余可用空间的长度
    int free;

    // 数据空间,默认是使用C字符串的空字符结尾的
    char buf[];
};

其中每项的含义已经在注释中说明。

通过上面的定义,我们可以看到,sds与传统的c字符串做了几方面的优化:

  1. 在sds中,记录了“字符数组”的的长度len;

  2. 通过使用free可以实现预分配策略优化。

通过这两方面的优化,我们可以得到以下方面的提升:

  1. 在做需要设计到内存扩展方面的操作的时候,只要检查free属性,就可以很容易得到是否需要扩展内存,从而避免内存溢出;

  2. 在获取字符串长度方面,再也不用花费O(N)时间复杂度,只主要获得len属性就可以得到长度,时间复杂度变为O(1);

  3. 我们知道,C字符串和底层数组之间是有密切联系的,因此每次增加或者缩短一个C字符串,都会涉及到对内存的分配,但是使用sds的len属性和free属性,可以减少内存的重分配次数。

关于上面提到的减少内存重分配优化方面,Redis做了两方面的优化,一个是空间预分配和惰性空间释放。

  1. 空间预分配:这方面的优化主要是用于字符串的增长操作:当用SDS的API来修改一个SDS,且需要进行空间扩展的时候,程序首先会为SDS分配修改所必须的空间,其次,还会分配额外的使用空间,这里面有两个策略:

    1. 当对SDS的内存进行修改后,SDS的长度已经超过1M了,那么Redis会自动的为这个SDS分配1M的free看空间;

    2. 当对SDS的内存进行修改后,SDS的长度小于1M,那么,Redis会自动给这个SDS分配等同于len的free空间。

  2. 惰性空间释放:对于传统的C字符串,如果我们要缩短,那么就一定要释放对应的内存,否则会导致内存泄露,但是Redis中的SDS,会把这部分内存用free来记住,所以,可以不用马上释放,这部分内存可以供以后使用,当然,Redis也提供了相关释放的API。

     

此外,我们对于传统的C字符串,我们只能存储简单的文本字符串,为什么呢?因为在传统的字符串中,我们是使用空字符来判断这个字符串是不是结束了,因此在字符串的中间就不能使用特殊的字符。这给要在多场景应用下的Redis带来了弊端,因此,在Redis的SDS中,并不是用简单的空字符来判断一个buf是不是已经结束了,而是要使用len属性来判断是不是已经结束,因此,在Redis的SDS中的buf 是可以存储文本字符串之外的数据的,因此,在Redis的SDS中,buf更多的是称作一个字节数组。当然,SDS中的buf 也是使用空字符来作为这个串的结尾的,这是为了兼容一部分C字符串的操作函数。

© 著作权归作者所有

共有 人打赏支持
会飞的杨先生
粉丝 9
博文 14
码字总数 30689
作品 0
昆明
CTO(技术副总裁)
加载中

评论(7)

grandfa
grandfa
桑总
会飞的杨先生
会飞的杨先生

引用来自“梁金堂”的评论

还是不够安全,毕竟可以任意修改任何字符

这个不是基于安全角度来考虑的呢,主要是基于性能来考虑的1
梁金堂
梁金堂
还是不够安全,毕竟可以任意修改任何字符
orangleliu
orangleliu
呵呵
会飞的杨先生
会飞的杨先生
多拍
orangebook
orangebook
:smiley::satisfied::satisfied::satisfied::satisfied::satisfied::satisfied:
韦龙舒
韦龙舒
‘哈哈哈
Redis设计思路学习与总结

版权声明:本文由宋增宽原创文章,转载请注明出处: 文章原文链接:https://www.qcloud.com/community/article/222 来源:腾云阁 https://www.qcloud.com/community 宋增宽,腾讯工程师,16年...

偶素浅小浅
2016/12/11
25
0
我的架构演化笔记 10:ElasticSearch的分词器之ansj研究

架构不变,为了学习方便,直接研究ElasticSearch-rtf版本。 ~~~ 关于redis---配置文件中指定

强子哥哥
2014/06/11
0
7
Redis源码分析系列七:initServer下

这个函数快到尾声了,一鼓作气! if(aeCreateTimeEvent(server.el, 1, serverCron, NULL, NULL) == AE_ERR) { redisPanic("Can't create the serverCron time event."); exit(1); } 这个函数......

强子哥哥
2013/10/18
0
0
Python Celery初研究

最近,换了一个工作环境去做研究,当然啦,新公司新作风,需要研究python并行分布式框架:Celery,不用多说,干呗。 然后就抽空看了一下,果然接口简单,开发容易,5分钟就写出了一个异步发送...

kumikoda
2017/04/03
0
0
【开源】.net 分布式架构之分布式缓存中间件

开源git地址: http://git.oschina.net/chejiangyi/XXF.BaseService.DistributedCache 分布式缓存中间件 方便实现缓存的分布式,集群,负载均衡,故障自动转移,并兼容多种缓存存储的分布式缓...

车江毅
2015/12/31
1K
0
.NET 分布式缓存中间件--XXF.BaseService.DistributedCache

分布式缓存中间件 方便实现缓存的分布式,集群,负载均衡,故障自动转移,并兼容多种缓存存储的分布式缓存中间件。 用于解决分布式架构中的分布式缓存环节。 特点: 代码少,便于扩展。 兼容...

车江毅
2015/12/31
848
1
滴滴出行java面试9个问题,你会几个?

此前,w3cschool app开发者头条发布了网易java面经、阿里巴巴java面经、小米java面经。 今天给程序员小伙伴们分享的是滴滴出行java面经。 通常而言,在学习java过程中,首先要学会自己抓住重...

W3Cschool
2017/12/08
0
0
Window64位安装Redis及管理工具

1、Redis安装 1.地址:http://www.nuget.org/packages/Redis-64/3.0.500,根据需要安装自己想要的版本 2.Windows安装非常简单,解压文件夹,点击redis-server启动Redis 3.点击redis-client,...

Java_Coder
2015/12/15
154
2
redis更新日志中文版2.4-2.6

2.4 -> 2.6 1.SORT命令不会对非数值类型(double)排序,适用于list,set (string 类型使用 sort alpha ) 2.EXPIRE相关命令都精确到了毫秒,不影响expire命令 3.INFO输出格式中增加了空行与注释...

屌丝Lee
2016/06/15
88
0
研究学习Kotlin的一些方法

Kotlin是一门让人感到很舒服的语言,相比Java来说,它更加简洁,省去了琐琐碎碎的语法工作,同时了提供了类似Lambda,String template,Null Safe Operator等特性。让开发者用起来得心应手。 ...

技术小黑屋
2017/05/08
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

eclipse SVN 项目重新定位

SVN 重新定位 1.方法一 首先:在Eclipse中选择Windows-> Show View->others 就会出现【SVN资源库/SVN Repositories】,选中后,点击确认; 然后:选中原有的地址,选择【重新定位/Relocate】...

qimh
9分钟前
0
0
Linux 第29课 ——Linux集群架构(下)

Linux集群架构(下) 八、DR模式搭建 8.1 准备工作 试验需求三台机器: 分发器,也叫调度器(简写为dir) 192.168.112.136 ying01 rs1 192.168.112.138 ying02 rs2 192.168.112.139 ying03 vip...

feng-01
14分钟前
0
0
轻松搭建svn版本管理工具+svnmanager管理客户端

前面的文章有写过svn版本管理工具的安装是基于svn的安装包进行安装,对于svn与apache的结合还得下svn和apache的模块进行结合过程比较繁琐,今天来介绍下通过centos的yum来安装svn能够快速安装...

javazyw
23分钟前
0
0
keepalived配置高可用集群

Linux集群概述 根据功能划分为两大类:高可用和负载均衡 高可用集群通常为两台服务器,一台工作,另外一台作为冗余,当提供服务的机器宕机,冗余将接替继续提供服务 实现高可用的开源软件有:...

TaoXu
29分钟前
0
0
mysql联表批处理操作

1 概述 mysql中的单表增删改查操作,可以说是基本中的基本. 实际工作中,常常会遇到一些基本用法难以处理的数据操作,譬如遇到主从表甚至多级关联表的情况(如一些历史问题数据的批量处理),考虑到...

社哥
31分钟前
0
0
IntelliJ IDEA 详细图解最常用的配置,适合刚刚用的新人。

刚刚使用IntelliJ IDEA 编辑器的时候,会有很多设置,会方便以后的开发,磨刀不误砍柴工。 比如:设置文件字体大小,代码自动完成提示,版本管理,本地代码历史,自动导入包,修改注释,修改...

kim_o
46分钟前
0
0
Google Java编程风格指南

目录 前言 源文件基础 源文件结构 格式 命名约定 编程实践 Javadoc 后记 前言 这份文档是Google Java编程风格规范的完整定义。当且仅当一个Java源文件符合此文档中的规则, 我们才认为它符合...

niithub
48分钟前
0
0
java.net.MalformedURLException异常说明

1.异常片段 Java代码中,在进行URL url = new URL(urllink)操作时,提示以下异常信息,该类异常主要问题出在参数urllink上面。 异常片段1 java.net.MalformedURLException at java.ne...

lqlm
48分钟前
1
0
CentOS7修改mysql5.6字符集

解决办法:CentOS7下修改MySQL数据库字符编码为UTF-8,UTF-8包含全世界所有国家所需要的字符集,是国际编码。 具体操作如下: 1.进入MySQL [root@tianqi-01 ~]# mysql -uroot -p Enter passw...

河图再现
50分钟前
0
0
DevExpress v18.1新版亮点——WPF篇(一)

用户界面套包DevExpress v18.1日前终于正式发布,本站将以连载的形式为大家介绍各版本新增内容。本文将介绍了DevExpress WPF v18.1 的新功能,快来下载试用新版本!点击下载>> Accordion Co...

Miss_Hello_World
53分钟前
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部