Redis 的 string

栏目: 数据库 · 发布时间: 5年前

内容简介: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_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》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

PHP 6与MySQL 5基础教程

PHP 6与MySQL 5基础教程

(美)厄尔曼 / 陈宗斌 等 / 人民邮电出版社 / 2008-11-1 / 65.00元

本书是一部经典的入门级著作,采用基于任务的方法来讲授PHP和MySQL,使用大量图片指导读者深入学习语言,并向读者展示了如何构造动态Web站点。书中用简洁、直观的步骤和讲解提供了学习任务和概念的最快方式。通过学习本书,读者可以快速、高效地掌握PHP和MySQL,成为一位构建Web站点的高手。 本书适合初中级Web应用开发和设计人员阅读。 本书是讲述PHP和MySQL技术的畅销书,以深入......一起来看看 《PHP 6与MySQL 5基础教程》 这本书的介绍吧!

HTML 压缩/解压工具
HTML 压缩/解压工具

在线压缩/解压 HTML 代码

CSS 压缩/解压工具
CSS 压缩/解压工具

在线压缩/解压 CSS 代码

URL 编码/解码
URL 编码/解码

URL 编码/解码