2. redis对象

104 阅读3分钟

我们常说的redis的数据类型实际上指的是redis对象 .

redis并没有直接使用前面介绍的数据结构来作为我们常说的字符串,list,set,sortset,map.

而是针对不同的情况,对同一个Redis对象采取多种数据结构类型.

对象结构体定义

typedef struct redisObject {
    unsigned int type;
    unsigned int encoding;
    void * prt;//指向底层具体的数据结构地址
    unsigned int refcount;//引用数量
    unsigned lru:22//最后一次访问时间
}

lru用于在设置了最大的maxmemory情况下,优先剔除那些长时间未访问的对象.

使用object idletime key 来查看对象已经多次时间未访问了.

type

指明对象的类型。

  1. redis_string
  2. redis_list
  3. redis_set
  4. redis_zset
  5. redis_hash

使用type key可以查询出指定对象的类型

其中string 对象是唯一一个可以在其他对象中使用的类型,例如list对象ptr指向的指针类型就是string。因为其能存int ,string 以及byte数组

encoding

指明对象的底层数据结构。

类型对应的数据结构
redis_encoding_int结构中的ptr直接强转为long
redis_encoding_enmstrembstr编码的sds
redis_encoding_rawsds
redis_encoding_htdict
redis_encoding_linkedlistlinklist
redis_encoding_skiplistskiplist
redis_encoding_ziplistziplist
redis_encoding_intsetintset

查询对象的encoding: object encoding key

1. redis_string的底层数据结构

  1. redis_encoding_int:

    例如set k 123456,底层的encoding为该值

  2. redis_encoding_embstr:

    字符串长度小于32个字节时,使用enmstr,本质上和redis_encoding_raw一样,只是redis_encoding_raw会调用两次内存分配函数,一次为创建redisObject,一次为sds.而redis_encoding_embstr只分配一次连续的内存空间给两个对象使用(不知道咋实现的),并且释放的时候也释放一次.

  3. redis_encoding_raw:

    当存储的字符串长度大于32个字节时,使用raw

redis是使用字符串来保存long double

2. redis_list的底层数据结构

  1. redis_encoding_ziplist

    内容保存到ziplist_entry

  2. redis_encoding_linkedlist

    保存的节点值是redisObject_string

当节点元素数量(512个)和节点内容大小(64字节)都小于括号内的值时,采用ziplist,否则升级为linkedlist.该值可修改.

3. redis_set的底层数据结构

  1. redis_encoding_intset
  2. redis_encoding_ht

4. redis_zset的底层数据结构

  1. redis_encoding_ziplist
  2. redis_encoding_skiplist 和 redis_encoding_ht

5. redis_hash的底层数据结构

  1. redis_encoding_ziplist

    存入时,先将key压入ziplist的尾部,然后把value压入ziplist.keyvalue都是一对存放的.

    查询的时候,遍历即可.

    问题是重复key如何处理? 查找覆盖。

  2. redis_encoding_ht

    keyvalue都是redisObject_string

    元素大小和数量的限制和redis_linkedlist相同.都是64byte512个元素

对象共享

Redis会在初始化服务器时,创建一万个字符串对象,这些对象包含了从0到9999的所有整数值,当服务器需要用到值为0到9999的字符串对象时,服务器就会使用这些共享对象,而不是新创建对象

对象共享只针对于0-9999的整数字符串.因为判断Redis对象相等的代价是就结构约复杂,越难判断.

使用object refcount key来查看引用次数

问题

  1. redis存储一个数字字符串,为什么底层显示的是int,而不是字符串?