Redis 的 string
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_RAW
、OBJ_ENCODING_INT
和 OBJ_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 字符串放在了同一块内存空间中。这种编码对内存空间优化不大,但是它们的空间是连续的。这样做,我认为有几个好处。
- 开辟和回收空间的时候,只需要进行一次操作就可以了,这样做减少了 malloc 和 free 的次数。
- 连续的空间,对系统缓存更加友好。
目前,是对长度小于 44 的小字符串进行这种编码。
0x04 OBJ_ENCODING_RAW
在前面的几种尝试都失败之后,就只能存储成最原始的动态字符串了。但是 Redis 在这里依然还是会做一点事情,就是会把动态字符串的多余的空间给释放掉,目前(5.0)是会释放掉 10% 长度的冗余空间,如果不足 10% 就不会释放。
0x05 后记
Redis 对内存的优化真是做到了极致,这里还只是冰山一角,我了解到的还只是冰山一角。
本文为作者自己读书总结的文章,由于作者的水平限制,难免会有错误,欢迎大家指正,感激不尽。
Redis 的 string相关推荐
- 一:redis 的string类型 - 相关操作
*redisclient使用: =============一类:string的方法================介绍:string是redis的最简单类型,一个key相应一个value,string ...
- 分布式内存数据库---Redis操作String、list、set、hash和Zset
Redis是一个Key-Value存储系统.和Memcached类似,它支持存储的value类型相对更多,包括string(字符串).list(链表).set(集合)和zset(有序集合).这些数据类 ...
- redis类型[string 、list 、 set 、sorted set 、hash]
Keys redis本质上一个key-value db,所以我们首先来看看他的key. 首先key也是字符串类型,但是key中不能包括边界字符:由于key不是binary safe的字符串,所以像&q ...
- Redis学习---(7)Redis 字符串(String)
Redis 字符串(String) Redis 字符串数据类型的相关命令用于管理 redis 字符串值,基本语法如下: 语法 redis 127.0.0.1:6379> COMMAND KEY_ ...
- Redis学习-string数据类型
Redis 是一个开源的使用 ANSI C 语言编写.支持网络.可基于内存亦可持久化的日志 型.Key-Value 数据库. redis提供五种数据类型string,hash,list,set及sor ...
- (Redis_学习一)Redis关于string类型和hash类型数据操作
Redis关于string类型和hash类型数据操作 set name xiaohongyang // get name setnx name xiaohy get name setex name 1 ...
- Redis数据类型-String(字符串类型)
String是redis最基本的类型,你可以理解成Memcached一模一样的类型,一个key对应一个value. String类型是二进制安全的,意思是redis的string可以包含任何数据,比如 ...
- Redis之String应用场景与SpringCache--存储对象信息、分布式唯一ID、文章阅读量、Lua脚本
String应用场景 一.存储对象信息 代码 重写Redis序列 解决方式 剖析SpringCache常用注解 @CacheConfig @Cacheable @CachePut @CacheEvic ...
- redis的String、List、Hash、SET、ZSet五中数据类型常用的一些场景总结
目 目录 1.String类型常见的使用场景 1.1 一般的业务功能模块,比如购物车 1.2 简单的字符缓存 1.3 储存结构体或者对象 1.4 计数功能 1.5 各类场景下(单机或分布式)的标识号 ...
最新文章
- [ C++ ] 理解const
- Chosen中选择项的更新
- linux zookeeper安装并设置开机自启
- mysql实验总结范文_数据库课程设计实验报告范例1
- python输出三角形周长_976. 三角形的最大周长(Python)
- 英特尔多核联合实验室授牌仪式
- 贝叶斯网的R实现( Bayesian networks in R)bnlearn(3)
- PNG免扣艺术字体素材|为年货季准备好了么?
- ui界面表单设计素材模板,实用可临摹
- hdu 5964:平行四边形 【计算几何】
- 大一c语言书课后题答案,C语言课后习题答案
- “猜猜红桃A在哪里”——android小游戏(入门学习必备)
- 如何解决设备管理中的难点?
- 4-7终极无敌DP乱秀
- 从零开始搭建完整的电影全栈系统(六)——影片Api示例、说明及应用
- Java系统答辩提问问题_宿舍管理系统答辩问题总结
- java发送outlook_在Outlook 2007中发送民意调查
- mysql导出表结构及数据的三种方法
- PID原理的详细分析及调节过程
- excel中将字符转换为数值