redis对数字/字符串append操作后,编码格式object encoding为什么从int/embstr变成raw了

一、实验环境

CentOS6.5Redis-5.0.4

二、问题描述

1.问题详情

127.0.0.1:6379> set a 5
OK
127.0.0.1:6379> type a
string
127.0.0.1:6379> object encoding a
int
127.0.0.1:6379> append a 666
4
127.0.0.1:6379> get a
5666
127.0.0.1:6379> object encoding a
raw
127.0.0.1:6379> 

疑问:

对数字a进行字符串操作append 666后,编码为什么由int变成raw,而不是变成embstr。
说好的,字符串长度小于等于44,编码格式是embstr的?

2.知识点科普

Redis的embstr编码方式和raw编码方式在3.2版本之前是以39字节为分界的,后续版本以44为分界。

也就是说,在redis5.0.4版本中,如果一个字符串值的长度小于等于44字节,则按照embstr进行编码,否则按照raw进行编码。

验证结果:

明显看到长度为44时,编码是embstr;大于44时,字符串对象将使用一个简单动态字符串(SDS)来保存这个字符串值, 并将对象的编码设置为 raw 。

127.0.0.1:6379> set w jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj   注:44个j
OK
127.0.0.1:6379> object encoding w
embstr
127.0.0.1:6379> set q jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj   注:45个j
OK
127.0.0.1:6379> object encoding q
raw

三、问题根源

《Redis设计与实现》 上说是因为embstr是只读的,任何修改操作都会转换成raw。

通过该答案也就是说,不单单int编码类型(type是string),进行字符串操作后,会自动转码为raw;对普通的短字符串(长度小于45个字节) 进行字符串操作后,编码格式也会发生改变(由原来的embstr变成raw)!

为了验证这个问题,继续往下看↓↓

四、验证答案

--数字案例,编码前后发生了变化
127.0.0.1:6379> set a 5
OK
127.0.0.1:6379> type a
string
127.0.0.1:6379> object encoding a
int
127.0.0.1:6379> append a 666
4
127.0.0.1:6379> get a
5666
127.0.0.1:6379> object encoding a
raw

--字符串案例,编码前后发生了变化
127.0.0.1:6379> set k hello
OK
127.0.0.1:6379> type k
string
127.0.0.1:6379> object encoding k   此时的编码是embstr
embstr
127.0.0.1:6379> append k  world     对k进行字符串w的操作
10
127.0.0.1:6379> get k
helloworld
127.0.0.1:6379> object encoding k    果然k被操作后,编码变成了raw
raw
127.0.0.1:6379> 

五、结论

《Redis设计与实现》 上说是因为embstr是只读的,任何修改操作都会转换成raw。

通过上面的试验结果,再次验证了这句话是正确的。

如果仅仅声明了一个字符串,长度小于45时,它的编码格式默认就是embstr,一旦被修改了,编码格式会自动提升为raw。

这个是redis的内部设计问题。 

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值