Redis学习目录总结03-Redis的对象类型与内部编码-字符串

146 阅读2分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第6天,点击查看活动详情

关于Redis内部编码的转换,都符合以下规律:

编码转换在Redis写入数据时完成,且转换过程不可逆,只能从小内存编码向大内存编码转换。(不包括重新set)

1、字符串

核心

  • Redis所有的键都是字符串类型
  • 字符串之外的其他几种复杂类型的元素也是字符串。
  • 字符串长度不能超过512MB。

内部编码

字符串类型的内部编码应用场景:

1、int:8个字节的长整型。字符串值是整型时,这个值使用long整型表示。

image.png

2、embstr:<=39字节的字符串。

image.png

3、raw:大于39个字节的字符串

image.png

embstr和raw有什么区别?

相同点:

  • embstr与raw都使用redisObject和sds保存数据, 不同点:
  • embstr 申请一次内存空间, 因为 RedisObject 和 SDS 是连续的
  • embstr 删除释放一次空间内存空间
  • embstr RedisObject 和 SDS 连在一起, 查找方便
  • embstr 扩容只读
  • raw 申请两次内存空间, 分别为 RedisObject 和 SDS 申请内存空间
  • raw 删除释放两次内存空间
  • raw RedisObject 和 SDS 不在一起, 查找不方便
  • raw 可单独为 RedisObject 和 SDS 扩容

结论:

  • embstr的好处在于创建时少分配一次空间,删除时少释放一次空间,以及对象的所有数据连在一起,寻找方便

  • embstr的坏处也很明显,如果字符串的长度增加需要重新分配内存时,整个redisObject和sds都需要重新分配空间,因此redis中的embstr实现为只读。

  • embstr和raw进行区分的长度,是39;是因为redisObject的长度是16字节,sds的长度是9+字符串长度;因此当字符串长度是39时,embstr的长度正好是16+9+39=64,jemalloc正好可以分配64字节的内存单元。

(3) int 和 embstr 转化为 raw 之间编码转换

  • 当 int 数据不再是整数, 或大小超过了 long 的范围 (2^63 - 1) 时, 自动转化为 raw

  • 由于 embstr 是只读的, 因此在对 embstr 对象进行修改时, 都会先转化为 raw 再进行修改, 无论是否达到了 44 个字节

image.png