内容简介:Redis 的字符串就是 SET 和 GET 操作对应的类型,算是 Redis 里最常用的类型了。Redis 内部的字符串表示,没有直接使用 C 语言字符串,而是对其进行了一定的改造,改造后的字符串在内存管理和长度计算方面的性能都有所提升。举个例子,假设要存储的是字符串”redis“。
Redis 的 string
Redis 的字符串就是 SET 和 GET 操作对应的类型,算是 Redis 里最常用的类型了。
0x00 动态字符串 sds
Redis 内部的字符串表示,没有直接使用 C 语言字符串,而是对其进行了一定的改造,改造后的字符串在内存管理和长度计算方面的性能都有所提升。
举个例子,假设要存储的是字符串”redis“。
+--------+--------+-------------+ | len | alloc | |r|e|d|i|s| | +--------+--------++-----------++ | | v v flag '\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
- 从源码看redis的string结构
- 蜻蜓点水说说Redis的String的奥秘
- Redis存储总用String?你大概错过了更优的使用方法
- 理解 Redis(4) - 关于 string 的更多命令(SETEX, SETNX, INCR, DECR, MSET...)
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
PHP 6与MySQL 5基础教程
(美)厄尔曼 / 陈宗斌 等 / 人民邮电出版社 / 2008-11-1 / 65.00元
本书是一部经典的入门级著作,采用基于任务的方法来讲授PHP和MySQL,使用大量图片指导读者深入学习语言,并向读者展示了如何构造动态Web站点。书中用简洁、直观的步骤和讲解提供了学习任务和概念的最快方式。通过学习本书,读者可以快速、高效地掌握PHP和MySQL,成为一位构建Web站点的高手。 本书适合初中级Web应用开发和设计人员阅读。 本书是讲述PHP和MySQL技术的畅销书,以深入......一起来看看 《PHP 6与MySQL 5基础教程》 这本书的介绍吧!