面试题41:介绍一下Redis中String类型的实现方式是什么?

2023-05-09 21:42:46 浏览数 (1)

【概述】

  • 适用场景 缓存业务信息,且只是根据key直接获取缓存value,不需要排序,去重等功能。
  • string是Redis中最简单的数据结构,但是却是大家日常使用频率最高的数据结构。
  • 它使用简单,并且扩展性非常的强。我们可以设置普通的字符串,也可以使用json存储复杂value信息。存取速度也是最快的。
  • 字符串存储的底层结构其实就是字符数组。
  • 这个字符串是动态的,是可修改的。内部采用预分配冗余空间的方式来减少内存的频繁分配。分配方式如下所示:
    • 当存储的字符串大小<=1M的时候,都是翻倍扩容。
    • 如果存储的字符串大小>1M的时候,则每次只扩容1M空间。
    • 字符串最大不能超过512M。

【内部实现】

  • 字符串对象可以使用intrawembstr这三种encoding。
  • 那么什么情况下选择什么encoding呢?

【int】

  • 如果保存的是可以用long类型表示的整数值,那么encoding为int。 示例如下所示:
代码语言:javascript复制
127.0.0.1:6379> set numbers 100
OK
127.0.0.1:6379> OBJECT encoding numbers
"int"

【embstr】

  • 保存的值小于40,则使用embstr
  • embstr编码是专门用于保存短字符串的一种优化编码方式。
  • 它与raw编码的区别是:
    • raw编码会调用两次内存分配函数来分别创建redisObject和sdshdr
    • 而embstr编码则通过调用一次内存分配函数来分配一块连续的空间包含redisObject和sdshdr。并且embstr编码的字符串对象的所有数据都保存在一块连续的内存里面,所以执行速度更快。
  • 示例如下所示:
代码语言:javascript复制
127.0.0.1:6379> set num 123456789012345678901234567890123456789
OK
127.0.0.1:6379> STRLEN num
(integer) 39
127.0.0.1:6379> OBJECT encoding num
"embstr"
  • Redis没有为embstr编码的字符串对象提供修程序,所以,embstr是只读的。如果我们对其进行修改,其实是先转换成raw,再执行修改命令。所以,修改后embstr就会变为raw编码的字符串对象了。如下所示:
代码语言:javascript复制
127.0.0.1:6379> set name muse
OK
127.0.0.1:6379> OBJECT encoding name
"embstr"
127.0.0.1:6379> APPEND name boy
(integer) 7
127.0.0.1:6379> OBJECT encoding name
"raw"
  • 数据结构如下所示:

【raw】

  • 保存的值大于等于40,则使用raw
代码语言:javascript复制
127.0.0.1:6379> set num 1234567890123456789012345678901234567890
OK
127.0.0.1:6379> STRLEN num
(integer) 40
127.0.0.1:6379> OBJECT encoding num
"raw"
  • 数据结构如下所示:

【编码转换规则】
  • 如果将原本保存的整数值转换为字符串值,那么字符串对象的编码也将从int变为raw。 如下所示:
代码语言:javascript复制
127.0.0.1:6379> set num 1234
OK
127.0.0.1:6379> OBJECT encoding num
"int"
127.0.0.1:6379> APPEND num a
(integer) 5
127.0.0.1:6379> get num
"1234a"
127.0.0.1:6379> OBJECT encoding num
"raw"

0 人点赞