redis对象之字符串对象
承接上文redis对象
前言
上文中描述了对象结构的几个属性,其中type表示redis五种对象类型,而encoding属性就是其对象类型的具体编码实现
字符串对象的编码实现可以是int,raw,embstr 三种,下面具体描述这三种编码实现的区别
编码实现方式
int
如果一个字符串对象保存的是整数值,并且这个整数值可以用long类型来表示,那么字符串对象就会将整数值保存在对象属性的ptr中,并经encoding属性设置为int
raw
如果一个字符串对象保存的是一个字符串值,并且该字符串的长度大于39字节,那么redis就会采用一个SDS来保存该字符串,并将encoding属性设置为raw
embstr
重点是embstr编码实现,如果一个字符串对象保存的是一个字符串值,并且该字符串值的长度小于等于39字节,那么redis会采用embstr编码的方式来保存这个字符串值
何为embstr?
embstr编码是一种专门用来保存短字符串的优化编码方式
至于为什么说是一种优化编码方式呢?因为和raw编码方式一样,embstr编码方式的实现也是使用redisObject对象接口以及sdshdr结构来表示字符串对象的,不同之处在于raw方式会调用两次内存分配来分别创建redisObject结构和sds结构,而embstr编码则通过调用一次内存分配函数来分配一块连续的内存空间,这个连续的内存空间中一次包含这两个结构
采用一次内存分配的好处?
-
创建embstr字符串对象,内存调用只需要一次,更快
-
释放embstr字符串对象,只需要一次内存释放即可,更快
-
由于是一块连续的内存空间,所以相比于raw方式的可以更好的利用缓存带来的优势。
既然embstr编码有这么多好处,那其缺点是什么呢?
缺点:
- embstr编码的字符串是只读的,redis没有为其编写任何的修改程序
那么当我们对一个embstr编码的字符串进行修改时,redis是如何处理呢?
编码的转换
当我们对一个embstr编码的字符串对象进行修改时,redis会进行编码的转换
何为编码转换?
-
当我们对于int编码的字符串对象修改,将其修改为一个不再是整数值,而是一个字符串值时,redis就会将该字符串对象的编码从int转为raw
-
当我们对于embstr编码的字符串对象执行修改时,由于embstr编码字符串对象是只读的,redis也会将其转为raw编码的字符串对象后再执行修改命令
总结
-
redis对象系统中的字符串对象的编码实现方式有三种,分别是int,embstr,raw
-
当redis字符串对象保存的值是整数值,且可以采用long类型表示时,redis会采用int编码方式来作为底层实现
-
特殊的embstr编码的字符串对象是一次内存内存调用,速度更快,但是其是只读的
-
当对只读的embstr字符串对象修改时,redis会进行编码转换,将embstr编码格式的转为raw格式的,再执行修改命令