首页 > GAME > 游戏 > 正文

曲靖沉曳叫商贸有限公司,昆明始挡集团有限责任公司,鸡西拿凰网络技术有限公司

ptr指向这个sds的空间


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数组中已使用的字节数,等同于字符串长度(不包括结尾的)
    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:6379> set test "123" 
OK
127.0.0.1:6379> object encoding test
"int"
// 插入long的最大值2^63-1
127.0.0.1:6379> set test "9223372036854775807" 
OK
127.0.0.1:6379> object encoding test
"int"
// 插入2^63,就不是int编码了
127.0.0.1:6379> set test "9223372036854775808" 
OK
127.0.0.1:6379> 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:6379> set test "hello"
    OK
    127.0.0.1:6379> object encoding test
    "embstr"
    127.0.0.1:6379> append test "world"
    (integer) 10
    127.0.0.1:6379> object encoding test
    "raw"
  • int编码在执行append前,也会先转为raw,再修改
  • int编码执行整数计算时(比如incrby)直接使用整数编码
  • raw和embstr编码,执行整数方法(比如incrby)时,如果其内容为long内的整数,则先转为int再执行,执行完还是int。如果内容不是long内的整数,则向客户端抛出异常

字符串命令详细实现:

 

 

当前文章:http://mabebox.com/88702.html

发布时间:2019-03-22 05:15:59

你的陨落,让世界失去了一位传奇---克里斯托弗·李 打造鼠目寸光的幸福女人 它把自己变大了 步非烟之所托非人 我要上小学了:成长营的第二天 千年之恋 圣诞节预热:诺心lecake星愿蛋糕真好吃! 报复方舟子的肖传国被自己的欲望锤倒了! 盘子里 不要让孩子未来孤苦无依

如果你够勇敢,此刻转个身,就能抱住你所爱的人 孩子早恋的父母们应该读的一篇美文:柳眉儿落了 恐惧的形成和消除 为了孩子,父母该不该守住破碎的婚姻 建国以来最大规模的阅兵-2015阅兵 美国宇航局发现新地球,可供居住未知 有些爱就是用来辜负的 油气是怎么被找到的? 妹子,你向往什么样的爱情? 来得及 低龄儿童培养的是领导力还是全能感? 文创优化 - 黄胤然首倡文化新概念 吸毒越来越普遍吗? 这四年我孩子没有适应伯克利,伯克利也没有记住他 难舍欲罢的男友关系 永远不要考验人性 罗李华语录 再次关注“被普通”的校园凶杀案的犯罪者 新时代的养育观——你知道么?

编辑:平海纯帝


声明:所发布的内容均来源于互联网,目的在于传递信息,但不代表本站赞同其观点及立场,版权归属原作者,如有侵权请联系删除。
调戏妹子胸小,结果......

认识自己是获得婚姻幸福的基础

罗李华谈:属鼠的人2016年运程