跟我一起来学习Redis中的字符串对象

399 阅读3分钟

这是我参与8月更文挑战的第6天,活动详情查看:8月更文挑战

一、字符串对象

1、字符串对象介绍及特性
2、编码的转换
3、字符串部分命令的实现

1、字符串对象介绍及特性

  字符串对象的编码可以是int、raw或者embstr。

  • 字符串对象保存的是整数值,并且这个整数值可以用long类型来表示,那么字符串对象会将整数值保存在字符串对象结构的ptr属性里面(将void*转换成long),并将字符串对象的编码设置为int。
  • 字符串对象保存的是一个字符串值,并且这个字符串值的长度大于39字节,那么字符串对象将使用一个简单动态字符串(SDS)来保存这个字符串值,并将对象的编码设置为raw。
  • 字符串对象保存的是一个字符串值,并且这个字符串值的长度小于等于39字节,那么字符串对象将使用embstr编码的方式来保存这个字符串值。

使用embstr编码的字符串对象来保存短字符串值有以下好处:
1、embstr编码将创建字符串对象所需的内存分配次数从raw编码的两次降低为一次。
2、释放embstr编码的字符串对象只需要调用一次内存释放函数,而释放raw编码的字符串对象需要调用两次内存释放函数。
3、因为embstr编码的字符串对象的所有数据都保存在一块连续的内存里面,所以这种编码的字符串对象比起raw编码的字符串对象能够更好地利用缓存带来的优势。

image.png

raw编码的字符串对象

image.png

embstr编码的字符串对象

最后注意的是,可以用long double类型表示的浮点数在Redis中也是作为字符串值来保存的。

2、编码的转换

int编码的字符串对象和embstr编码的字符串对象在条件满足的情况下,会被转换为raw编码的字符串对象。
1、对于int编码的字符串对象来说,如果我们向对象执行了一些命令,使得这个对象保存的不再是整数值,而是一个字符串值,那么字符串对象的编码从int变为raw。
2、Redis没有为embstr编码的字符串对象编写任何相应的修改程序(只有int编码的字符串对象和raw编码的字符串对象有有这些程序),所以embstr编码的字符串对象实际上是只读的,当我们对embstr编码的字符串对象进行修改时,程序就会发生转换。

以下示例,展示一个embstr编码的字符串对象在执行APPEND命令之后,对象的编码从embstr变为raw的例子:

redis> SET msg "hello world"
OK
redis> OBJECT ENCODING msg
"embstr"
reids> APPEND msg " again!"
(integer) 18
redis> OBJECT ENCODING msg
"raw"