Redis 的 string

Redis 的字符串就是 SET 和 GET 操作对应的类型,算是 Redis 里最常用的类型了。

0x00 动态字符串 sds

Redis 内部的字符串表示,没有直接使用 C 语言字符串,而是对其进行了一定的改造,改造后的字符串在内存管理和长度计算方面的性能都有所提升。

举个例子,假设要存储的是字符串”redis“。

+--------+--------+-------------+
|  len   | alloc  | |r|e|d|i|s| |
+--------+--------++-----------++|           |v           vflag        '\0'

这个图就是 sds 的内存结构。sdshdr 分四个部分,从左往右一次是字符串长度、开辟的内存空间、sdshdr 的类型以及字符串本身。在字符串初始化好之后,会返回一个指针,指向字符串本身的首地址,也就是 r 的内存地址。这样,既能方便地享受 C 语言字符串带来的兼容性,又可以对内存管理了如指掌。

0x01 redisObj

typedef struct redisObject {unsigned type:4;unsigned encoding:4;unsigned lru:LRU_BITS; /* LRU time (relative to global lru_clock) or* LFU data (least significant 8 bits frequency* and most significant 16 bits access time). */int refcount;void *ptr;
} robj;

这是 Redis 的对象的结构,每一个 key 或者 value 都会存储成这样一个结构体。可以看一下第二个成员变量 encoding。这是 Redis 对这个对象做的编码操作。,Redis string 在存储的时候,会努力进行三种方式的编码,分别是 OBJ_ENCODING_RAWOBJ_ENCODING_INTOBJ_ENCODING_EMBSTR,针对这三种编码,尽可能地进行去优化内存空间。

最后一个成员变量则是指向具体的内容,如字符串类型的对象就直接指向对应的 sds 字符串的地址。

0x02 OBJ_ENCODING_INT

Redis 在拿到了用户 SET 命令的字符串后,如果用户 SET 了一个纯数字字符串,就会做这种优化。这种优化有一个好处,可以看到 redisObject 中的 ptr 变量,这是一个指针,也就意味着,这个变量占据 8 个字节的内存空间。8 个字节的内存空间,刚好可以存储一个 64 位的整数。Redis 会判断字符串的长度是不是小于 20,如果小于 20 则会尝试将字符串整数化。这里的 20 是因为 64 位整型可以表示的范围是 [-9223372036854775808,9223372036854775807]。

这样做了之后,就不需要额外的空间为这个“字符串”生成一个动态字符串,直接存在 ptr 就可以了。

0x03 OBJ_ENCODING_EMBSTR

Redis 在转换成整型失败后,就会尝试这种编码。这种编码其实是把 robj 和 sds 字符串放在了同一块内存空间中。这种编码对内存空间优化不大,但是它们的空间是连续的。这样做,我认为有几个好处。

  1. 开辟和回收空间的时候,只需要进行一次操作就可以了,这样做减少了 malloc 和 free 的次数。
  2. 连续的空间,对系统缓存更加友好。

目前,是对长度小于 44 的小字符串进行这种编码。

0x04 OBJ_ENCODING_RAW

在前面的几种尝试都失败之后,就只能存储成最原始的动态字符串了。但是 Redis 在这里依然还是会做一点事情,就是会把动态字符串的多余的空间给释放掉,目前(5.0)是会释放掉 10% 长度的冗余空间,如果不足 10% 就不会释放。

0x05 后记

Redis 对内存的优化真是做到了极致,这里还只是冰山一角,我了解到的还只是冰山一角。

本文为作者自己读书总结的文章,由于作者的水平限制,难免会有错误,欢迎大家指正,感激不尽。

Redis 的 string相关推荐

  1. 一:redis 的string类型 - 相关操作

    *redisclient使用: =============一类:string的方法================介绍:string是redis的最简单类型,一个key相应一个value,string ...

  2. 分布式内存数据库---Redis操作String、list、set、hash和Zset

    Redis是一个Key-Value存储系统.和Memcached类似,它支持存储的value类型相对更多,包括string(字符串).list(链表).set(集合)和zset(有序集合).这些数据类 ...

  3. redis类型[string 、list 、 set 、sorted set 、hash]

    Keys redis本质上一个key-value db,所以我们首先来看看他的key. 首先key也是字符串类型,但是key中不能包括边界字符:由于key不是binary safe的字符串,所以像&q ...

  4. Redis学习---(7)Redis 字符串(String)

    Redis 字符串(String) Redis 字符串数据类型的相关命令用于管理 redis 字符串值,基本语法如下: 语法 redis 127.0.0.1:6379> COMMAND KEY_ ...

  5. Redis学习-string数据类型

    Redis 是一个开源的使用 ANSI C 语言编写.支持网络.可基于内存亦可持久化的日志 型.Key-Value 数据库. redis提供五种数据类型string,hash,list,set及sor ...

  6. (Redis_学习一)Redis关于string类型和hash类型数据操作

    Redis关于string类型和hash类型数据操作 set name xiaohongyang // get name setnx name xiaohy get name setex name 1 ...

  7. Redis数据类型-String(字符串类型)

    String是redis最基本的类型,你可以理解成Memcached一模一样的类型,一个key对应一个value. String类型是二进制安全的,意思是redis的string可以包含任何数据,比如 ...

  8. Redis之String应用场景与SpringCache--存储对象信息、分布式唯一ID、文章阅读量、Lua脚本

    String应用场景 一.存储对象信息 代码 重写Redis序列 解决方式 剖析SpringCache常用注解 @CacheConfig @Cacheable @CachePut @CacheEvic ...

  9. redis的String、List、Hash、SET、ZSet五中数据类型常用的一些场景总结

    目 目录 1.String类型常见的使用场景 1.1 一般的业务功能模块,比如购物车 1.2 简单的字符缓存 1.3 储存结构体或者对象 1.4 计数功能 1.5 各类场景下(单机或分布式)的标识号 ...

最新文章

  1. [ C++ ] 理解const
  2. Chosen中选择项的更新
  3. linux zookeeper安装并设置开机自启
  4. mysql实验总结范文_数据库课程设计实验报告范例1
  5. python输出三角形周长_976. 三角形的最大周长(Python)
  6. 英特尔多核联合实验室授牌仪式
  7. 贝叶斯网的R实现( Bayesian networks in R)bnlearn(3)
  8. PNG免扣艺术字体素材|为年货季准备好了么?
  9. ui界面表单设计素材模板,实用可临摹
  10. hdu 5964:平行四边形 【计算几何】
  11. 大一c语言书课后题答案,C语言课后习题答案
  12. “猜猜红桃A在哪里”——android小游戏(入门学习必备)
  13. 如何解决设备管理中的难点?
  14. 4-7终极无敌DP乱秀
  15. 从零开始搭建完整的电影全栈系统(六)——影片Api示例、说明及应用
  16. Java系统答辩提问问题_宿舍管理系统答辩问题总结
  17. java发送outlook_在Outlook 2007中发送民意调查
  18. mysql导出表结构及数据的三种方法
  19. PID原理的详细分析及调节过程
  20. excel中将字符转换为数值

热门文章

  1. ThreadLocal类的实现用法
  2. sed替换字符时 ' /等符号的处理
  3. FinTech领域的风险控制——风险篇
  4. Android 不能勾选 Project Build Target
  5. Mybatis 开发 dao 的方法
  6. js实现点击按钮传值
  7. 《迷宫》之站立会议—5.16
  8. 【原创】StreamInsight查询系列(十)——基本查询操作之联接
  9. 陕西西咸新区暨沣渭新区泾渭新区网上截图!
  10. Hyper-V虚拟机Redhat添加网卡找不到网卡配置文件解决方法