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, " ...
随机推荐
- CSS 背景图像 background属性简写
background属性简写 background属性可以像margin padding属性一样,有简写方法,它的简写顺序是: background-color background-image ba ...
- SVN添加用户
1. 找到svn安装路径 /svn/repositories/ (如果不知道,可以搜索 :find / -name svn或者是ps -ef | grep svn) 2.进入该目录的conf,其中包 ...
- 工程启动没有报错,但是dubbo后台显示没有提供者,工程没有提供服务
先说一下我遇到的问题:服务工程启动没有异常,消费者工程启动会出现很多nested(嵌套的)错误,但其根本错误是No provider available(缺少服务提供者).可是服务工程起来的时候明明没 ...
- java表达式中运算符优先级
运算符优先级:运算符*和/(以及%)的优先级高于+和-(优先级越高,越早运算) 在逻辑运算符中,!拥有最高优先级,之后是&&,接下来是||. 一般来说,相同优先级的运算符的运算顺序是从 ...
- List和符号分隔的字符串互相转换
一.将逗号分隔的字符串转换成List: 1. 使用JDK的Arrays类: import java.util.Arrays; import java.util.List; public class T ...
- Django2 SQLite3迁移到MySQL数据库
https://blog.csdn.net/weixin_34257076/article/details/86843658
- Python学习—数据库篇之pymysql
一.pymysql简介 对于Python操作MySQL主要使用两种方式: 原生模块 pymsql ORM框架 SQLAchemy pymsql是Python中操作MySQL的模块,其使用方法和MySQ ...
- 制作docker基础镜像
docker build -t tomcat:jre8-alpine . sudo docker tag 5a3 registry.cn-shenzhen.aliyuncs.com/ibase/tom ...
- itchat 报错 OSError: [WinError -2147221003] 找不到应用程序: 'QR.png'
OSError: [WinError -2147221003] 找不到应用程序: 'QR.png' 原因: 缺少在windows 下相关处理方法 解决方法:找到你运行环境C:\Python36\L ...
- nginx学习笔记(一)
agentzh 的 Nginx 教程 学习笔记 nginx的变量 Nginx 变量一旦创建,其变量名的可见范围就是整个 Nginx 配置,甚至可以跨越不同虚拟主机的 server 配置块, 例子如下 ...