
Redis 内部针对 string提供了三种编码格式,分别是:int,embstr,raw

一、字符串编码选择流程

- int编码:8个字节的长整形,当数字长度小于20同时能够被强制转换成long long 类型使用 int编码,长度大于20,或者超出 long long 类型范围的时候会转换使用embstr
- embstr编码:小于等于44字节的字符串
- raw编码:大于44个字节的字符串
二、验证编码选择流程

2.1、int 编码验证
在 [-9223372036854775808,9223372036854775808] 范围内的数字使用的 int编码格式(闭区间)
左边负数阈值
127.0.0.1:6379> set age -9223372036854775808
127.0.0.1:6379> STRLEN age
(integer) 20
127.0.0.1:6379> OBJECT encoding age
"int"
# 超出阈值,使用 embstr
127.0.0.1:6379> set age -9223372036854775809
127.0.0.1:6379> STRLEN age
(integer) 20
127.0.0.1:6379> OBJECT encoding age
"embstr"
右边正数阈值
127.0.0.1:6379> set age 9223372036854775807
127.0.0.1:6379> STRLEN age
(integer) 19
127.0.0.1:6379> OBJECT encoding age
"int"
## 超出阈值,使用 embstr
127.0.0.1:6379> set age 9223372036854775808
127.0.0.1:6379> STRLEN age
(integer) 19
127.0.0.1:6379> OBJECT encoding age
"embstr"
"int"2.2、embstr 验证
不符合 int编码标准,同时最大的字符长度小于等于 44字节,使用 embstr 编码格式。
127.0.0.1:6379> set age 11111111112222222222333333333344444444445555
OK
127.0.0.1:6379> STRLEN age
(integer) 44
127.0.0.1:6379> OBJECT encoding age
"embstr"
## 字符长度大于 44字节,使用 raw 编码格式
127.0.0.1:6379> set age 111111111122222222223333333333444444444455556
OK
127.0.0.1:6379> STRLEN age
(integer) 45
127.0.0.1:6379> OBJECT encoding age
"raw"2.3、raw编码格式
字符长度大于 44字节的字符串,同时字符长度小于 512M
三、sds能够存储多大字符串

以 sdshdr32 为例。
在 sds 结构定义中,alloc 是用来表示当前 sds 结构允许容纳的最大字符长度,sdshdr32 对应 alloc 的单位为 uintt32_t,而 uintt32_t 的取值范围是:0~2^32 = 4294967296
也就是说 sdshdr32 理论上允许存储的 char数组长度为 4294967296 ,而 一个 char 字符占用一个字节,换算后的单位如下:

也就是 sdshdr32理论上允许存储4个G的数据,那 sdshdr64理论值就更大了,不过也仅仅是理论值
Redis 在内部会存在一个上限值:512M,也就是一个字符串最大允许你存储 512M的字符串。
所以理论上 sds 结构能够存储的字符串很大,不过 Redis 对字符串做了限制,限制最大的字符串长度为512M。