之前介绍了多种数据结构
字符串 链表 字典 跳表 压缩列表 整数集合
接下来 介绍 这些数据结构在 Redis对象中的使用以及变化
Redis对象系统 包括: 字符串对象 列表对象 哈希对象 集合对象 有序集合对象
对象使用了至少1种以上的数据结构,并且在条件发生变化时会进行数据结构的改变
其对象实现了基于引用计数法的内存回收机制!!!!内存碎片问题如何解决?
Redis中每个对象都由一个redisObject结构表示:
typedef struct redisObject {
//类型
unsigned type:4;
//编码
unsigned encoding:4;
//指向底层实现数据结构的指针
void *ptr;
} robj;
type属性记录了对象的类型,该属性的值为下面中的一个:
REDIS_STRING 字符串对象
REDIS_LIST 列表对象
REDIS_HASH 哈希对象
REDIS_SET 集合对象
REDIS_ZSET 有序集合对象
对于Redis, 键总是一个字符串对象,值可以是上述中的一种
使用 键值对 时 至少会创建两个对象 一个键对象 一个值对象
如:SET msg "hello redis" 其中键对象:msg 字符串对象 值对象:hello redis 字符串对象
对象的ptr指针指向对象的底层数据结构。这个数据结构由对象的encoding属性决定
encoding属性可以是下面常量中的一个:
REDIS_ENCODING_INT long类型的整数
REDIS_ENCODING_EMBSTR embstr编码的简单动态字符串
REDIS_ENCODING_RAW 简单动态字符串
REDIS_ENCODING_HT 字典
REDIS_ENCODING_LINKEDLIST 双向链表
REDIS_ENCODING_ZIPLIST 压缩列表
REDIS_ENCODING_INTSET 整数集合
REDIS_ENCODING_SKIPLIST 跳跃表 和 字典
每种类型的变量至少使用了两种不同的编码
1 五种对象的底层编码:
字符串类型对象:REDIS_ENCODING_INT REDIS_ENCODING_EMBSTR REDIS_ENCODING_RAW
列表类型的对象:REDIS_ENCODING_ZIPLIST REDIS_ENCODING_LINKEDLIST
哈希对象:REDIS_ENCODING_ZIPLIST REDIS_ENCODING_HT
集合对象:REDIS_ENCODING_INTSET REDIS_ENCODING_HT
有序集合对象:REDIS_ENCODING_ZIPLIST REDIS_ENCODING_SKIPLIST
2 编码转换条件
A: 保存的是整数值 并且此整数值可以用64位长整型表示 则将encoding设置为int,并将ptr的类型由void *转为long
B: 保存的是一个字符串,并且字符串长度大于39字节 则将encoding设置为raw, 使用 普通 SDS保存此对象
C: 存的是一个字符串,并且字符串长度小于等于39字节 则将encoding设置为embstr, 使用emb SDS保存此对象
emb一次性创建redisObject以及sdshdr,并且内存是连续的
优点:
a 内存分配次数由两次缩减到一次
b 释放内存次数由两次缩减到一次
c 连续的内存空间访问效率更快
当为int且64位可以处理时,使用endcoding为int进行存储
当变为str且字节小于等于39字节时,使用embstr进行存储
当对embstr进行增长 字符串长度大于39字节时,使用普通 SDS存储此对象。
API:
SET
GET
APPEND
INCRBYFLOAT
INCRBY
DECRBY
STRLEN
SETRANGE
GETRANGE
3 命令在编码上的作用原理
根据2进行推测 其中浮点数采用SDS进行存储