一、字符串对象(String)对应的底层数据的编码类型
- OBJ_ENCODING_IN:使用整数值实现的字符串对象
- OBJ_ENCODING_EMBSTR:使用 embstr 编码的简单动态字符串实现的字符串对象
- OBJ_ENCODING_RAW:使用简单动态字符串实现的字符串对象
区别:
- OBJ_ENCODING_IN:ptr直接存储整型值
- OBJ_ENCODING_EMBSTR:一次性分配内存,存储
redisObject
结构和sdshdr
结构 - OBJ_ENCODING_RAW:两次单独分配内存,存储
redisObject
结构和sdshdr
结构
二、底层数据结构的设置原则
Redis 可以根据不同的使用场景来为一个对象自动设置不同的数据存储结构, 来优化对象在某一场景下的效率
- 如果值是
long
类型的整数,则编码类型为OBJ_ENCODING_IN - 如果值是long类型整数,且在0-9999中,则使用系统预设的共享对象,并refcount增加1
- 如果值为字符串,且长度小于39字节,则编码类型为OBJ_ENCODING_EMBSTR,因为redis中使用jemalloc分配和回收内存,一次性分配存储64字节的连续内存。
- 如果值为字符串,且长度大于39字节,则编码类型为OBJ_ENCODING_RAW
三、字符串命令的实现
命令 | int 编码的实现方法 |
embstr 编码的实现方法 |
raw 编码的实现方法 |
---|---|---|---|
SET | 使用 int 编码保存值。 |
使用 embstr 编码保存值。 |
使用 raw 编码保存值。 |
GET | 拷贝对象所保存的整数值, 将这个拷贝转换成字符串值, 然后向客户端返回这个字符串值。 | 直接向客户端返回字符串值。 | 直接向客户端返回字符串值。 |
APPEND | 将对象转换成 raw 编码, 然后按raw 编码的方式执行此操作。 |
将对象转换成 raw 编码, 然后按raw 编码的方式执行此操作。 |
调用 sdscatlen 函数, 将给定字符串追加到现有字符串的末尾。 |
INCRBYFLOAT | 取出整数值并将其转换成 longdouble 类型的浮点数, 对这个浮点数进行加法计算, 然后将得出的浮点数结果保存起来。 |
取出字符串值并尝试将其转换成long double 类型的浮点数, 对这个浮点数进行加法计算, 然后将得出的浮点数结果保存起来。 如果字符串值不能被转换成浮点数, 那么向客户端返回一个错误。 |
取出字符串值并尝试将其转换成 longdouble 类型的浮点数, 对这个浮点数进行加法计算, 然后将得出的浮点数结果保存起来。 如果字符串值不能被转换成浮点数, 那么向客户端返回一个错误。 |
INCRBY | 对整数值进行加法计算, 得出的计算结果会作为整数被保存起来。 | embstr 编码不能执行此命令, 向客户端返回一个错误。 |
raw 编码不能执行此命令, 向客户端返回一个错误。 |
DECRBY | 对整数值进行减法计算, 得出的计算结果会作为整数被保存起来。 | embstr 编码不能执行此命令, 向客户端返回一个错误。 |
raw 编码不能执行此命令, 向客户端返回一个错误。 |
STRLEN | 拷贝对象所保存的整数值, 将这个拷贝转换成字符串值, 计算并返回这个字符串值的长度。 | 调用 sdslen 函数, 返回字符串的长度。 |
调用 sdslen 函数, 返回字符串的长度。 |
SETRANGE | 将对象转换成 raw 编码, 然后按raw 编码的方式执行此命令。 |
将对象转换成 raw 编码, 然后按raw 编码的方式执行此命令。 |
将字符串特定索引上的值设置为给定的字符。 |
GETRANGE | 拷贝对象所保存的整数值, 将这个拷贝转换成字符串值, 然后取出并返回字符串指定索引上的字符。 | 直接取出并返回字符串指定索引上的字符。 | 直接取出并返回字符串指定索引上的字符。 |
四、PHP调用方法
参考:http://www.cnblogs.com/zcy_soft/archive/2012/09/21/2697006.html
Pingback引用通告: Redis中的对象类型与底层编码 | 精彩每一天