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, " ...
随机推荐
- SUSE11sp3 perf工具安装过程
工作环境是suse11sp3系统(内核版本3.0.101-0.47.90-default),需要通过perf排查系统性能问题,但是默认是没有perf工具的. 在网上搜索了一下,需要linux-tool ...
- windows系统如何安装运行filebeat
下载安装包 下载地址:https://www.elastic.co/downloads/beats/filebeat 解压到指定目录,无需安装 打开解压后的目录,打开filebeat.yml进行配置. ...
- python的bit_length方法
bit_length方法作用是得到指定数值的二进制的长度数.宽度数 举例: age=1 v=age.bit_length() print(v) 返回结果: 1 #数值1对应的二进制是1,长度1位 ...
- I/O系统(二)
程序查询流程1测试指令,查询IO设备是否就绪.2传送指令,当已经就绪时,执行传送功能.3转移指令,未就绪时,转移至继续测试IO设备的状态.当需要启动某一IO设备时,必须将该程序插入到现行程序中.1,由 ...
- 20175126《Java程序设计》第五周学习总结
# 20175126 2016-2017-2 <Java程序设计>第五周学习总结 ## 教材学习内容总结 - 本周学习方式主要为手动敲代码并理解内容学习. - 学习内容为教材第六章,本章内 ...
- Ubuntu 16.04 安装Kinect V2驱动
1.下载源代码 git clone https://github.com/OpenKinect/libfreenect2.git 2.依赖项安装 sudo apt-get install build- ...
- aop point-cut表达式
好多博客写的云里雾里,大多都有一点毛病.大家还是以官网为准 @官网文档 官网截图 modifiers-pattern:修饰符 ret-type-pattern:方法返回类型 declaring-typ ...
- FragmentManager中Fragment的重复创建、复用问题
当我们在Activity中使用 Fragment可以用FragmentManager去添加到对应个ViewGoup中使用 FragmentManager fragmentManager = getSu ...
- [并查集][NOIP2015]信息传递
信息传递 题目描述 有 N 个同学( 编号为 1 到 N) 正在玩一个信息传递的游戏. 在游戏里每人都有一个固定的信息传递对象, 其中,编号为i的同学的信息传递对象是编号为ti的同学. 游戏开始时, ...
- 3,postman的变量写法和collection
1,环境变量和全局变量的添加和引用 pm.globals.get("variable_key");可以引用环境变量 2,collection的使用 当在tests中使用文件变量的时 ...