Redis数据结构之字符串-SDS
C
语言中,传统的字符串表示是以空字符结尾的字符数组,Redis
的字符串没有直接使用该表示,而是选择构建了一种名为简单动态字符串(simple dynamic string, SDS)
的抽象类型。
在Redis
中,C
字符串只会作为字符串字面量(string literal)
用在一些无需对字符串值进行修改的地方,例如打印日志等场景。
结构
struct SDS<T> {
T capacity; // 数组容量
T len; // 数组长度
bytes flags; // 特殊标识位
bytes[] content; // 字节数组,存储字符串
};
capacity
:分配给字节数组的长度len
:字节数组存储内容的实际长度
Redis
规定字符串长度不能超过512M
。
绝大部分情况下,认为不会对字符串进行append
操作,所以创建字符串时len
和capacity
一样长,即不分配冗余空间。
SDS
对比C
字符串
获取字符串长度时间复杂度为
O(1)
:直接使用len
属性有效杜绝缓冲区溢出:
APPEND
操作先分配空间,再执行拼接减少修改字符串可能带来的内存重分配次数:空间预分配,动态扩容提供冗余空间
二进制安全:
SDS
使用len
的值而不是空字符来判断字符是否结束,所以字节数组可以用来保存一系列二进制数据兼容部分
C
字符串函数
扩容策略
Redis
的字符串扩容策略主要根据字符串长度len
来区分。
len
小于1M
时,采用加倍策略,即保留100%
的冗余空间。
len
超过1M
之后,为避免加倍后的冗余空间过大而导致浪费,每次扩容只分配1M
冗余空间。
embstr
和raw
Redis
的字符串有两种存储方式:
embstr
:将RedisObject
对象头和SDS
对象连续存在一起,使用malloc
方法一次性分配raw
:使用两次malloc
,两个对象头在内存地址上不连续
不同存储形式的转换:
对于
SDS
字符串,如果长度小于等于39
个,则使用embstr
形式存储,否则使用raw
形式存储-
>>> set a aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
>>> STRLEN a >>> OBJECT ENCODING a
"embstr"
>>> set b aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
>>> STRLEN b >>> OBJECT ENCODING b
"raw"
-
对于
embstr
,该字符串实际上是只读的,对该对象执行任何修改命令后时,Redis
会先将对象编码转为raw
,然后执行修改命令>>> set a hello
>>> OBJECT ENCODING a
"embstr"
>>> APPEND a world
>>> OBJECT ENCODING a
"raw"
Redis数据结构之字符串-SDS的更多相关文章
- 峰Redis学习(3)Redis 数据结构(字符串、哈希)
第一节:Redis 数据类型介绍 五种数据类型: 字符串(String) 字符串列表(list) 有序字符串集合(sorted set) 哈希(hash) 字符串集合(set) 第二节:Redis ...
- Redis 数据结构之字符串的那些骚操作
Redis 字符串底层用的是 sds 结构,该结构同 c 语言的字符串相比,其优点是可以节省内存分配的次数,还可以... 这样写是不是读起来很无聊?这些都是别人咀嚼过后,经过一轮两轮三轮的再次咀嚼,吐 ...
- Redis自定义动态字符串(sds)模块(一)
Redis开发者在开发过程中没有使用系统的原始字符串,而是使用了自定义的sds字符串,这个模块的编写是在文件:sds.h和sds.c文件中.Redis自定义的这个字符串好像也不是很复杂,远不像ngin ...
- 如何使用RedisTemplate访问Redis数据结构之字符串操作
Redis 数据结构简介 Redis 可以存储键与5种不同数据结构类型之间的映射,这5种数据结构类型分别为String(字符串).List(列表).Set(集合).Hash(散列)和 Zset(有序集 ...
- Redis自定义动态字符串(sds)模块(二)
sds模块的具体实现: 1.sdsnewlen 根据参数生成一个sds字符串 sds sdsnewlen(const void *init, size_t initlen) { struct sdsh ...
- Redis数据结构之字符串
学习阶段分成两个部分,一个是redis客户端,一个是java客户端操作 一:在redis客户端操作 1.先删除里面的几个key 2.set与get与getset 3.数值的增减 值递增1,或者减一 如 ...
- redis 5.0.7 源码阅读——动态字符串sds
redis中动态字符串sds相关的文件为:sds.h与sds.c 一.数据结构 redis中定义了自己的数据类型"sds",用于描述 char*,与一些数据结构 typedef c ...
- 【Redis笔记(四)】 Redis数据结构 - list链表
原创作品,转载请标明:http://blog.csdn.net/Xiejingfa/article/details/50573605 经过前面的介绍,我们学习了Redis中string字符串.hash ...
- Redis数据结构之简单动态字符串SDS
Redis的底层数据结构非常多,其中包括SDS.ZipList.SkipList.LinkedList.HashTable.Intset等.如果你对Redis的理解还只停留在get.set的水平的话, ...
随机推荐
- Springboot的Mybatis逆向工程
1.pom.xml添加mybatis和逆向插件依赖: <dependency> <groupId>org.mybatis.spring.boot</groupId> ...
- java性能调优03
1.java中的四种引用类型(级别由高到低为:强引用,软引用,弱引用和虚引用) 1.1 强引用:默认创建的变量都是强引用,垃圾回收机制不会将其回收,当内存空 间不足,Java虚拟机宁愿抛出OutOfM ...
- mavenFailed to execute goal org.apache.maven.plugins:maven-surefire-plugin解决方法
在项目上右键==>属性==>java构建路径==>源代码,然后把几个文件夹全部删除,然后再添加文件夹中把它们从新添加,然后再maven intall,部署.
- Docker部署web环境之Lanmt
2. 案例二 整套项目多容器分离通过docker-compose部署lanmt环境 详细的安装准备环境,省略,配置以及部署参考案例一即可 即可实现批量创建web,也可以实现多web共用一个php或my ...
- ORA-01000 error
ORA-01000是最大开放游标错误,是Oracle数据库开发中极为常见的错误. 在Java的上下文中,当应用程序尝试打开更多ResultSet而不是数据库实例上的已配置游标时,会发生这种情况. 解决 ...
- 【Luogu】【关卡1-8】BOSS战-入门综合练习2(2017年10月)【AK】------都是基础题
P1426 小鱼会有危险吗 我个人觉得这个题目出的不好,没说明白,就先只粘贴的AC代码吧 #include <bits/stdc++.h> using namespace std; int ...
- ZedGraph怎样在生成曲线时随机生成不一样的颜色
场景 在使用ZedGraph生成多条曲线时为了能区分曲线颜色,要求随机设置曲线颜色. 首先从System.Drawing.Color中获取所有颜色的对象的数组,然后将其顺序打乱随机排序,然后在生成曲线 ...
- c# 通过地址下载流然后保存文件到本地
1.下载文件并保存文件到本地 private void GetFileFromNetUrl(string url) { try { System.Net.WebRequest req = System ...
- Nginx---文档(从入门到精通)
very good http://tengine.taobao.org/book/index.html
- bzoj1066题解
[解题思路] 考虑拆点,把每根石柱拆成两个点,具体可以理解为石柱底部和石柱顶部,能爬到石柱顶部的蜥蜴只有有限只,而且蜥蜴只有爬到了石柱顶部才能跳到其他石柱的底部. 这样,考虑如下建图: 将每个有蜥蜴的 ...