Redis 数据结构之简单动态字符串SDS
几个概念
1:key对象 数据库存储键值对的键,总是一个字符串对象。
2:value对象 数据库存储键值对的值,可以是字符串对象,list对象,hash对象,set对象,sorted set对象。
例如:
set msg "hello world" 则redis在数据库中创建一个新的键值对,键和值都是一个字符串对象,底层实现都是一个sds对象。
rpush fruits "apple" "banana" "cherry" 则redis在数据库中创建一个新的键值对,键是一个字符串对象,底层实现是一个sds对象;值是一个列表对象,列表对象包含了三个字符串对象,由三个sds对象实现。
3:sds (sample dynamic string)
定义:
struct sdshdr{
//记录buf数组中已使用字节的数量
//等于sds所保存字符串的长度
int len;
//记录buf数组中未使用的字节数量
int free;
//字节数组用来保存字符串
char buf[];
}
4:C语言的简单字符串的表示方式不能满足redis对字符串在安全性、效率以及功能上的要求,故引用sds字符串
4.1 sds字符串获取字符串长度效率更高,时间复杂度为o(1),c字符串的为o(n),保证获取长度的工作不会成为redis的性能瓶颈。(更新sds长度工作是由sds的api在执行时自动完成的);
4.2 杜绝缓冲区溢出 s1如果没有分配足够的内存空间,扩展时s1的数据就会溢出到下一个相邻的s2空间中,而sds的空间分配时,api会先检查sds的空间是否满足修改所需的要求,如果不满足,api会自动将sds空间扩展到执行修改所需的大小,然后在执行修改操作;
4.3 减少修改字符串时带来的内存重新分配次数
1) c字符串执行加长操作,如果忘记重新分配内存就会出现缓冲区溢出,如果执行缩短操作,如果忘了重新分配内存就会出现内存泄露,由于redis是数据库,对速度要求苛刻,如果数据频繁修改,使用c字符串就需要频繁执行内存分配,执行内存分配就会占据修改字符串的大部分时间,如果频繁发生,还会对性能造成影响,故redis使用sds字符串作为底层的实现。
2) sds字符串 buf数组长度不一定等于字符数量加一,数组包含未使用字节,这个长度存储在free属性上
3) 空间预分配:优化sds字符串增长操作,api对sds进行空间扩展的时候,程序不仅会为sds修改所需的空间,还会为sds分配额外的未使用空间 公式:扩展后小于1m,分配和len属性相同的未使用空间,大于等于1m分配1m的未使用空间。这样在执行扩展操作时,api会先检查未使用空间是否足够,如果足够就直接使用未使用空间,减少内存分配次数,基于这种策略,在执行n次修改操作时,重新分配内存次数从n次降为最多n次。
4) 惰性空间释放:优化字符串缩短操作,在进行缩短操作时,程序不会立即重新分配内存回收缩短后多余出来的字节,而是使用free属性记录起来,等待将来使用,如果有增长操作可以直接使用。当然sds也提供了释放sds未使用空间的api,所以不必担心惰性释放带来的内存浪费问题。
4.4 二进制安全 c字符串中必须符合某种编码,出来字符串末尾,不能包含空字符,所以c字符串只能保存文本数据,不能存储图片、音频、视频等二进制数据,sds的api会以二进制的方式处理buf数组里的数据。使得redis可以保存任意格式的二进制。
4.5 兼容部分c函数 sds遵循空字符结尾的惯例,api会将sds保存数据的末尾设置为空字符,并且会在buf分配空间时多分配一个字节,这样可以让保存文本数据的sds重用string.h库定义的一些函数。
小结:
c字符串获取长度复杂度o(n),sds为o(1)
api不安全可能造成缓冲区溢出,api安全不会造成缓冲区溢出
修改字符串长度n次会执行n次内存分配,最多n次
只能保存文本数据,可以保存文本或二进制数据
可使用所有string.h库函数,只能使用部分函数
Redis 数据结构之简单动态字符串SDS的更多相关文章
- Redis数据结构之简单动态字符串SDS
Redis的底层数据结构非常多,其中包括SDS.ZipList.SkipList.LinkedList.HashTable.Intset等.如果你对Redis的理解还只停留在get.set的水平的话, ...
- redis 系列3 数据结构之简单动态字符串 SDS
一. SDS概述 Redis 没有直接使用C语言传统的字符串表示,而是自己构建了一种名为简单动态字符串(simple dynamic string, SDS)的抽象类型,并将SDS用作Redis的默 ...
- Redis数据结构之简单动态字符串
Redis没有直接使用C语言传统的字符串表示(以空字符结尾的字符数组), 而是自己构建了一种名为简单动态字符串(simple dynamic string,SDS)的抽象类型, 并将SDS用作Redi ...
- Redis核心原理-简单动态字符串SDS
SDS简介 Redis是C语言编写的,但没有使用c语言的字符串结构,而是自己实现了一套简单动态字符串 simple dynamic string 简称SDS,SDS兼容C语言的字符串类型,原理类似Ja ...
- 图解Redis之数据结构篇——简单动态字符串SDS
图解Redis之数据结构篇--简单动态字符串SDS 前言 相信用过Redis的人都知道,Redis提供了一个逻辑上的对象系统构建了一个键值对数据库以供客户端用户使用.这个对象系统包括字符串对象 ...
- Redis底层探秘(一):简单动态字符串(SDS)
redis是我们使用非常多的一种缓存技术,他的性能极高,读的速度是110000次/s,写的速度是81000次/s.这么高的性能背后,到底是怎么样的实现在支撑,这个系列的文章,我们一起去看看. redi ...
- 深入理解Redis 数据结构—简单动态字符串sds
Redis是用ANSI C语言编写的,它是一个高性能的key-value数据库,它可以作用在数据库.缓存和消息中间件.其中 Redis 键值对中的键都是 string 类型,而键值对中的值也是有 st ...
- 【redis】redis底层数据结构原理--简单动态字符串 链表 字典 跳跃表 整数集合 压缩列表等
redis有五种数据类型string.list.hash.set.zset(字符串.哈希.列表.集合.有序集合)并且自实现了简单动态字符串.双端链表.字典.压缩列表.整数集合.跳跃表等数据结构.red ...
- 【Redis】简单动态字符串SDS
C语言字符串 char *str = "redis"; // 可以不显式的添加\0,由编译器添加 char *str = "redis\0"; // 也可以添加 ...
随机推荐
- 《深入理解Android2》读书笔记(三)
接上篇<深入理解Android2>读书笔记(二) PackageManagerService PackageManagerService负责系统中Package的管理,应用程序的安装.卸载 ...
- Flask实战第40天:图片验证码生成技术
图片验证码生成 安装pillow pip install pillow 在utils下新建python package命名为captcha 把需要需要用到的字体放在captcha下 编辑captcha ...
- oracle return code 2112
SQL-02112 SELECT..INTO returns too many rows Cause: A SELECT...INTO statement returned more rows tha ...
- Xamarin.Forms获取设备屏幕大小
Xamarin.Forms获取设备屏幕大小 可以借助device.Display获取.基本形式如下: var display = device.Display;然后就可以获取屏幕大小.display. ...
- [BZOJ 1058] 报表统计
Link: BZOJ 1058 传送门 Solution: 为了这道题今天下午一直都在和常数大战…… 1.对于询问1,我们记录每个数末位置的数$T[i]$和初始位置$S[i]$ 用平衡树维护所有差值, ...
- 【虚树】hdu6161 Big binary tree
题意:一棵n个结点的完全二叉树,初始i号结点的权值为i.有两种操作:单点修改:询问经过某个结点的路径中,权值和最大的路径的权值和是多少. 修改的时候,暴力修改到根节点的路径上的点的f(x)即可. 跟虚 ...
- 【斜率优化】bzoj3675-[Apio2014]序列分割&&Uoj104
题目大意 将一个长度为N的非负整数序列分割成k+l个非空的子序列,每次选择一位置分割后,将会得到一定的分数,这个分数为两个新序列中元素和的乘积.求最大的分数. [UOJ104]并输出任意一种方案 思路 ...
- BUG:upstream timed out (10060: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected
更换Apache扑向Nginx,刚搭建完WNMP,nginx能访问php页面 但是访问现有开发项目报错 [error] 4112#3724: *9 upstream timed out (10060: ...
- 深入解析SQL Server并行执行原理及实践
http://dbaplus.cn/news-21-431-1.html
- Fork & vfork & clone (转载)
转自:http://blog.csdn.net/zqy2000zqy/archive/2006/09/04/1176924.aspx 进程是一个指令执行流及其执行环境,其执行环境是一个系统资源的集合, ...