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>读书笔记(七) AMS中的进程管理 AMS对进程的管理仅涉及两个方面 1.调节进程的调度优先级和调度策略 2.调节进程的oom值 调度优先级和调度策略 1 ...
- 在Spring Controller中将数据缓存到session
Servlet方案 在Controller的方法的参数列表中,添加一个javax.servlet.http.HttpSession类型的形参.spring mvc会 自动把当前session对象注入这 ...
- Linux命令之sort
sort [选项] [文件] 对文本文件的行进行排序.常见的字符排序空字符串<数字<a<A<b<B...<z<Z (1).常用选项 -b,--ignore-l ...
- 旺财C# .NET代码生成器之DTcms4/5代码批量生成功能
经近半年的实战积累.于2017年6月底,增加对第三方开源软件DTcms(4和5都支持)的代码生成支持. 可以一键生成的DTcms4/5代码如下:1.Model经典三层实体2.DAL经典三层数据库访问层 ...
- webpack2 热加载js 文件
如果只要普通的热加载 只要如下配置就好了 package.json { "devDependencies": { "webpack": "^2.6.1 ...
- Oracle关于锁的几种类型和参数
设立封锁机制主要是为了对并发操作进行控制,对干扰进行封锁,保证数据的一致性和准确性.Oracle数据库封锁方式有三种:共享封锁,独占封锁,共享更新封锁 封锁类型 Oracle RDBMS的封锁类型可分 ...
- POJ2975 Nim 博弈论 尼姆博弈
http://poj.org/problem?id=2975 题目始终是ac的最大阻碍. 问只取一堆有多少方案可以使当前局面为先手必败. 显然由尼姆博弈的性质可以知道需要取石子使所有堆石子数异或和为0 ...
- 【搜索】【约数个数定理】[HAOI2007]反素数ant
对于任何正整数x,其约数的个数记作g(x).例如g(1)=1.g(6)=4.如果某个正整数x满足:g(x)>g(i) 0<i<x,则称x为反质数. 所以,n以内的反质数即为不超过n的 ...
- linux之rootfs (UBIFS)
转:http://www.360doc.com/content/11/1208/15/3700464_170655736.shtml 大大小小事情一堆,好久不更新了,这次记录下移植ubifs文件系统步 ...
- PostgreSQL配置文件--实时统计
7 实时统计 RUNTIME STATISTICS 7.1 Query/Index Statistics Collector 下面的参数控制是否搜集特定的数据库运行统计数据 7.1.1 track_a ...