动态字符串(SDS)动态字符串的结构体如下

文章插图
这里解释一下结构体中各个成员变量的作用:
- len:已经保存的字符串字节数 , 不包含结束标示
- alloc:申请的总的字节数 , 不包含结束标示
- flags:不同的 SDS 的头类型 , 用来控制 SDS 的头大小
- buf[]:真正存储数据
在 redis 中 , 为了尽可能地节省内存空间 , 当字符串长度在不同的区间时 , 会选择不同的结构体 , 例如:
- 当字符串长度在 0~255 个字节之间时 , 会选择 hisdshdr8 , 这样一来 , 用于表示字符串字节数和申请的总字节数的空间就会被大大节省 , 以此类推 。

文章插图
例如 , 一个包含字符串“name”的 sds 结构如下:

文章插图
SDS之所以叫做动态字符串 , 是因为它具备动态扩容的能力 , 例如一个内容为 “hello” 的 SDS , 假如我们要给这个 SDS 追加一段字符串 ”world” , 这里首先会申请新内存空间:
- 如果新字符串小于1M , 则新空间为扩展后字符串长度的两倍+1
- 如果新字符串大于1M , 则新空间为扩展后字符串长度+1M+1 。
String 的三种编码方式RAW
- raw 是 string 的基本编码方式 , 基于简单动态字符串(SDS)实现 , 存储上限为512mb 。当一个字符串采用 raw 的编码方式的时候 , 它的结构如图所示 。

文章插图
EMBSTR
- 如果存储在 SDS 中的数据小于等于 44 字节 , 则会采用 EMBSTR 编码 , 此时 **RedisObject 与 SDS 是一段连续空间 。而不是像 RAW 的编码方式一样 , 由 ptr 指向另外一片空间 , **申请内存时只需要调用一次内存分配函数 , 效率更高 。结构如下 ,
而 redisObject 和 hisdshdr8 中 len alloc flags三个成员变量加起来刚刚好是 16 + 4 = 20 字节 , 如果 char[] (数据大小)的大小为 44 字节时 , 加起来刚刚好是 64 字节 , 也即 26 不会产生内存碎片 。
- RAW 和 EMBSTR 的编码演示

文章插图
INT
- 如果存储的字符串是整数值 , 并且大小在 LONG MAX 范围内 , 则会采用 INT 编码
- 直接将数据保存在 RedisObject 的 ptr 指针位置(刚好8字节) , 不再需要SDS了 。

文章插图
- INT 编码演示

文章插图
写在最后:在使用 string 类型时 , 尽可能让其长度小于 44 字节 , 或者使用整数表示 , 使其使用 EMBSTR 和 INT 编码
推荐阅读
- Redis有哪些持久化方式?一文带你了解技术存储的魅力!
- 什么是王者荣耀中的羊群效应?零和博弈到底是什么?
- 王者荣耀射手辅助中后期最强英雄!你们都知道是谁吗?
- 王者知识:对抗路人才百出,谁能成为玩家心目中的完美战神呢?
- 王者里操作简单,伤害很高的中单法师,遇到一定要针对
- 那些玩家心目中操作难度很大的英雄,快来看看吧!
- 武汉|武汉市中心医院招人,有岗位放宽到50岁
- 富婆|里皮:纵观中国足坛30年,仅有这5个人配得上叫巨星
- 赵雅芝|中国第一美女,如今65岁无儿无女,颜值不减赵雅芝!
- 医生|不怕“中年危机”的三个职业,工资水平中等偏上,越老越吃香
