redis对象
  • 简介:redis用来存储键值对数据,而键值对数据在redis内部以redis对象的形式存储。

  • 结构:

    1. typedef struct redisObject {
    2. // 类型
    3. unsigned type:4;
    4. // 编码
    5. unsigned encoding:4;
    6. // 对象最后一次被访问的时间
    7. unsigned lru:REDIS_LRU_BITS; /* lru time (relative to server.lruclock) */
    8. // 引用计数
    9. int refcount;
    10. // 指向实际值的指针
    11. void *ptr;
    12. } robj;
  • Type:对象的数据类型

    • REDIS_STRING
    • REDIS_LIST
    • REDIS_HASH
    • REDIS_SET
    • REDIS_ZSET
  • Encoding:

    • 对象的底层实现,与type对应。
    • 不同类型对应不同函数集合,决定对象可以执行哪些函数。
  • refcount:表示redis对象的引用数量,为零则回收。
  • lru:对象的最后一次被访问的时间戳。

    • 字符串对象:type=REDIS_STRING
  • encoding=int,ptr存储long类型的地址

    • 场景:保存的是整数,且处于long型的范围内。
  • encoding=raw,ptr存储SDS类型的地址

    • 场景:保存的是字符串,且长度大于32字节。
  • encoding=embstr,ptr存储SDS类型的地址

    • 场景:保存的是字符串,且长度小于等于32字节。
    • 好处:采用一次申请同时分配redisobject和sds的地址。释放内存也只有一次。由于空间连续可以更好利用缓存优势。
  • long double浮点数类型,也是用2,3来存储的,即采用sds字符串存储。当进行某些操作时会转换回double类型。
  • 当执行某些命令时,int没有提供对应的函数实现,就会转换成raw。如append等。embstr类型是只读的,没有任何函数实现,执行任何修改命令都会转换成raw。

    • 列表对象
  • encoding=ziplist,ptr存储压缩列表的地址

    • 场景:同时满足列表对象存储的字符串元素长度都小于64字节,数量小于512个。
  • encoding=linkedlist,ptr存储双端链表的地址

    • 场景:不满足上个场景。
      • 哈希对象
  • encoding=ziplist,ptr存储压缩列表的地址

    • 场景:存储的所有键值对的大小都小于64字节,数量小于512个。
  • encoding=hashtable,ptr存储字典的地址

    • 场景:不满足上个场景。
      • 集合对象
  • encoding=intset,ptr存储整数集合的地址

    • 场景:元素都是整数且数量小于512个。
  • encoding=hashtable,ptr存储字典的地址

    • 场景:不满足上个场景。
      • 有序集合对象
  • encoding=ziplist,ptr存储压缩列表的地址

    • 先存成员,紧接着存分值,按分值有序排列。
    • 场景:存储的所有键值对的大小都小于64字节,数量小于128个。
  • encoding=skiplist,ptr存储zset的地址
    1. typedef struct zset{
    2. zskiplist *zsl;
    3. dict *dict;
    4. }
  1. - 场景:不满足上个场景。
  2. - 其他:同时使用跳表和字典两种数据结构。字典的key是成员值,value是分值。好处是查分值o(1),范围型操作如zrank,时间复杂度太高。
  • 多态命令

    • del等命令是所有类型key都能执行,只是根据type及encoding不同,调用不同api。
    • 类型特定命令:执行前检查type,如果满足判断encoding,根据编码不同,说明底层实现不同,然后调用不同底层数据结构的api。
  • 对象共享

    • redis在初始化服务器时,会创建从0到9999的所有整数值,当要使用整数字符串时,会共享整数池中的对象。
    • 只会共享整数,不会共享字符串及其他更复杂的数据类型。因为要判断是否相等时间复杂度高。
  • 对象的空转时长

    • OBJECT IDLETIME命令会打印键的空转时长,通过当前时间减去lru得到。但该命令并不会更新lru。
    • 当开启maxmemory选项时,空转时长较高的键会被释放。