redis_字符串对象
Redis总共支持五种数据类型:string,hash,list,set及zset。这里介绍字符串类型的实现
首先了解字符串对象的结构
// redis对象内存分配,列出主要相关的属性
redisObject {
// 对于字符串对象,type = REDIS_STRING
type
// 字符串的底层编码,有三种:int、raw、embstr,后文介绍
encoding
// 指向实际保存字符串内容的空间
ptr
// 还有其他属性
......
}
上面的redisObject不实际保存字符串内容,而是通过ptr指向实际保存字符串内容的空间,叫sdshdr(Simple Dynamic String hdr 简单动态字符串)
struct sdshdr {
// 记录buf数组中已使用的字节数,等同于字符串长度(不包括结尾的\0)
int len;
// 记录buf数组中未使用的字节数
int free;
// 实际保存字符串的字节数组
char buf[];
}
这个sdshdr比较厉害,在字符串变长的时候可以预申请额外内存、缩短时不直接释放内存以备未来变长使用,等。
sdshdr的详细看这里:https://www.cnblogs.com/loveCheery/p/9133343.html
字符串编码
字符串对象有三种可能的底层编码:int、raw、embstr。
这三种编码格式是字符串对象底层空间分配的不同,对上层调用没有区别,不同编码的字符串对象在执行命令时效果是一样的
int编码
如果字符串保存的值是整数,范围在long之内,那么encoding会被设置为int,并且直接将证书值保存在ptr里(ptr不再指向一个复杂的sds结构了,直接是整数值)
// 插入long之内的值为整数的字符串
127.0.0.1:> set test ""
OK
127.0.0.1:> object encoding test
"int"
// 插入long的最大值2^63-1
127.0.0.1:> set test ""
OK
127.0.0.1:> object encoding test
"int"
// 插入2^63,就不是int编码了
127.0.0.1:> set test ""
OK
127.0.0.1:> object encoding test
"embstr"
raw编码
如果字符串保存的值长度比较大,那么encoding为raw,值使用sds(简单动态字符串),ptr指向这个sds的空间
比较大:《Redis设计与实现》里说长度大于39字节时,n多文章说长度大于32字节时,我测试返回长度大于44时才行,没查到是配置可选的还是redis版本指定的
总的来说就是对于大字符串,redis采用一套机制来控制字符串变长变短时的内存分配策略,实现是用的sds
embstr编码
如果字符串保存的值不是整数,并且长度不是很大,那么encoding为embstr,值也是sds,ptr指向这个sds的空间
embstr编码是专门用于保存段字符串的一种优化编码方式
- embstr和raw的实际字符串存储都是用了sds,区别在于:
- embstr编码的字符串对象,其所有数据保存在一块连续的内存空间中(redisObject和其ptr指向的sds在连续的内存空间),只需要一次内存分配操作
- raw编码的字符串对象,redisObject和其ptr指向的sds是不连续的,需要两次内存分配
embstr的内存空间连续的优势
- 其创建时的内存分配、释放时的内存回收次数都只有1次
- 方便预读取一段空间内的数据做缓存
其他
- embstr只读,没有修改方法。当对embstr编码的字符串做修改时,会先转为raw、再修改
127.0.0.1:> set test "hello"
OK
127.0.0.1:> object encoding test
"embstr"
127.0.0.1:> append test "world"
(integer)
127.0.0.1:> object encoding test
"raw"- int编码在执行append前,也会先转为raw,再修改
- int编码执行整数计算时(比如incrby)直接使用整数编码
- raw和embstr编码,执行整数方法(比如incrby)时,如果其内容为long内的整数,则先转为int再执行,执行完还是int。如果内容不是long内的整数,则向客户端抛出异常
字符串命令详细实现:

redis_字符串对象的更多相关文章
- 字符串对象-String
新建字符串对象 ① 直接赋值 ② 构造函数 ③ 转换函数 1 length 字符串对象属性 2 match() null 跟php中的preg_matc ...
- json对象与json字符串对象格式
var cStr = "{\"c\":\"{\\\"b\\\":\\\"000\\\",\\\"b2\\\&q ...
- js-string字符串对象
js-string字符串对象 一.String 对象描述 字符串是 JavaScript 的一种基本的数据类型. String 对象的 length 属性声明了该字符串中的字符数. String 类定 ...
- 关于Redis中的字符串对象
一.SDS redis中定义Object types有5种 /* Object types */ #define REDIS_STRING 0 #define REDIS_LIST 1 #define ...
- PHP“Cannot use object of type stdClass as array” (php在调用json_decode从字符串对象生成json对象时的报错)
php再调用json_decode从字符串对象生成json对象时,如果使用[]操作符取数据,会得到下面的错误 错误:Cannot use object of type stdClass as arra ...
- [BS-01] 根据字符串对象的参数自动计算用来显示该字符串的UI控件的宽和高
根据字符串对象的参数自动计算用来显示该字符串的UI控件的宽和高 1. 影响昵称Label的高和宽的因素: 字体和字号大小.文字多少.高度取决于是否固定了宽度(是否限制了最大的宽度和高度) 2. 使用 ...
- javascript字符串对象
String字符串对象 1. 字符串粗体展示: var a = "陈冠希喜欢拍电影"; document.writeln(a.bold()+"<br/>& ...
- javascript中的字符串对象和数组对象
1.javascript的对象的概念 在javascript中,除了null和undefined以处,其他的数据类型都被定义成了对象 也可以用创建对象的方法定义变量,string,math,array ...
- json字符串对象内嵌json对象
有时候需要在json的key:value字符串对象中再嵌入一个json对象,如果需要把如下的json对象作为字符串嵌入到json字符串对象中: { "type": 2, " ...
随机推荐
- repo
repo init -b remoteBranchName repo sync repo start localBranchName --all 整体切分支 if error is tagger cl ...
- springCloud面试题
1.SpringCloud和Dubbo SpringCloud和Dubbo都是现在主流的微服务架构SpringCloud是Apache旗下的Spring体系下的微服务解决方案Dubbo是阿里系的分布式 ...
- ELK日志分析平台搭建
ELK平台介绍 在搜索ELK资料的时候,发现这篇文章比较好,于是摘抄一小段: 以下内容来自:http://baidu.blog.51cto.com/71938/1676798 日志主要包括系统日志.应 ...
- CHROME浏览器清缓存
- win7安装oracle 10g问题总结。
1.安装oracle10g的时候,出现此问题,如图: 右键安装程序(setup.exe) -> 属性 -> 兼容性 -> 以兼容模式运行这个程序 windows xp( servi ...
- Earth Wind 一个查看全球风向的网站
可以查看整个地球的全貌 ,还能定位你的位置,特别是动画挺有意思 网址:https://earth.nullschool.net/#current/wind/surface/level/orthogra ...
- android 组件隐藏
参考 https://blog.csdn.net/bbtianshi/article/details/79556609 view.setVisibility(View.GONE);
- DVWA中low级的sql注入漏洞的简单复现
第一次成功复现一个简单漏洞,于是写下这篇随笔记录一下 首先我们来看dvwa中low级的sql注入的源码 源码文件路径如下图: 源码如下: <?php if(isset($_GET['Submit ...
- 远程过程调用(RPC)
在第二篇教程中我们介绍了如何使用工作队列(work queue)在多个工作者(woker)中间分发耗时的任务. 可是如果我们需要将一个函数运行在远程计算机上并且等待从那儿获取结果时,该怎么办呢?这就是 ...
- 2018-2019-2 20175126谢文航 实验一《Java开发环境的熟悉》实验报告
一.实验报告封面 课程:Java程序设计 班级:1751班 姓名:谢文航 学号:20175126 指导教师:娄嘉鹏 实验日期:2019年3月28日 实验时间:--- 实验序号:实验一 实验名称:Jav ...