Redis 的 string

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

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

查看所有标签

猜你喜欢:

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

数字战争

数字战争

[英]查尔斯·亚瑟 / 余淼 / 中信出版社 / 2013-6-1 / 49

1998年,数码世界初具雏形。 至此以往,大浪淘沙。随着IT产业的迅猛发展,涌现出了以苹果、谷歌、微软为首的行业巨头。它们为争夺数码世界不同分支的霸主地位而争斗,包括搜索技术、移动音乐、智能手机和平板电脑市场。它们可利用的武器包括硬件、软件以及广告。同时,它们要赌上的则是公司的声望,当然,还有我们的未来。然而,无论在产品创新还是在战略优势上,这些企业彼此竞争、彼此砥砺,推动了行业的良性发展。......一起来看看 《数字战争》 这本书的介绍吧!

MD5 加密
MD5 加密

MD5 加密工具

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试