zoukankan      html  css  js  c++  java
  • redis 对象

      redis是C语言编写的,内部用到的主要数据结构如下:

    简单动态字符串(SDS)、双端链表、字典、压缩列表、整数集合等待。

      redis并没有直接使用这些数据结构来实现键值对数据库,而是基于这些数据结构创建了一个对象系统,这

    个系统包含字符串对象、列表对象、哈希对象、集合对象和有序集合对象这五种类型的对象,每种对象都用到

    了至少一种数据结构。

      通过这五种不同类型的对象,redis可以在执行命令之前,根据对象的类型来判断一个对象是否可以执行

    给定的命令。使用对象的另一个好处是,我们可以针对不同的使用场景,为对象设置多种不同的数据结构实现

    ,从而优化对象在不同场景下的使用效率。

      redis的对象带有访问时间记录信息,该信息可以用于计算数据库键的空转时长,在服务器启用了max-

    memory功能的情况下,空转时长较大的那些键可能会优先被服务器删除。

    结构

     1 /* A redis object, that is a type able to hold a string / list / set */
     2 
     3 /* The actual Redis Object */
     4 /*
     5  * Redis 对象
     6  */
     7 #define REDIS_LRU_BITS 24
     8 #define REDIS_LRU_CLOCK_MAX ((1<<REDIS_LRU_BITS)-1) /* Max value of obj->lru */
     9 #define REDIS_LRU_CLOCK_RESOLUTION 1000 /* LRU clock resolution in ms */
    10 typedef struct redisObject {
    11 
    12     // 类型
    13     unsigned type:4;
    14 
    15     // 编码
    16     unsigned encoding:4;
    17 
    18     // 对象最后一次被访问的时间
    19     unsigned lru:REDIS_LRU_BITS; /* lru time (relative to server.lruclock) */
    20 
    21     // 引用计数
    22     int refcount;
    23 
    24     // 指向实际值的指针
    25     void *ptr;
    26 
    27 } robj;

    类型type

      对象的type属性记录了对象的类型,这个属性的值可以是如下

    1 /* Object types */
    2 // 对象类型
    3 #define REDIS_STRING 0
    4 #define REDIS_LIST 1
    5 #define REDIS_SET 2
    6 #define REDIS_ZSET 3
    7 #define REDIS_HASH 4

       对于redis保存的键值对来说,键总是一个字符串对象,而值则可以是字符串对象、列表对象、哈希

    对象、集合对象或者有序集合对象的其中一种,这里说的是值对应的对象

      TYPE命令可以查询键值对中对应的值对象的类型,而不是键对象的类型:

     

     encoding

      对象的ptr指针指向对象的底层实现数据结构,而这些数据结构由对象的encoding属性决定。

      encoding属性记录了对象的编码,也即是说这个对象使用率什么数据结构作为对象的底层实现,如下

     1 /* Objects encoding. Some kind of objects like Strings and Hashes can be
     2  * internally represented in multiple ways. The 'encoding' field of the object
     3  * is set to one of this fields for this object. */
     4 // 对象编码
     5 #define REDIS_ENCODING_RAW 0     /* Raw representation */
     6 #define REDIS_ENCODING_INT 1     /* Encoded as integer */
     7 #define REDIS_ENCODING_HT 2      /* Encoded as hash table */
     8 #define REDIS_ENCODING_ZIPMAP 3  /* Encoded as zipmap */
     9 #define REDIS_ENCODING_LINKEDLIST 4 /* Encoded as regular linked list */
    10 #define REDIS_ENCODING_ZIPLIST 5 /* Encoded as ziplist */
    11 #define REDIS_ENCODING_INTSET 6  /* Encoded as intset */
    12 #define REDIS_ENCODING_SKIPLIST 7  /* Encoded as skiplist */
    13 #define REDIS_ENCODING_EMBSTR 8  /* Embedded sds string encoding */

      每种类型的对象都至少使用了两种不同的编码,如下列出了每种类型的对象可以使用的编码

      使用OBJECT ENCODING命令可以查看一个数据库键的值对象的编码:

     

      

      通过encoding属性来设定对象所使用的编码,而不是为特定类型的对象关联一种固定的编码,极大地

    提升了redis的灵活性和效率,因为redis可以根据不同的使用场景来为一个对象设置不同的编码,从而优化

    对象在某一个场景下的效率。

      举个例子,在列表对象包含的元素比较少时,redis使用压缩列表作为列表对象的底层实现:

      1、压缩列表比双端列表更节约内存,并且在元素数量较少时,在内存中以连续块方式保存的压缩

    列表比起双端链表可以更快被载入到缓存中;

      2、随着列表对象包含的元素越来越多,使用压缩列表来保存元素的优势逐渐消失时,对象就会将底层

    实现从压缩列表转向功能更强、也更适合保存大量元素的双端链表上面;

      其它类型的对象也会通过使用多种不同的编码来进行类似的优化

  • 相关阅读:
    互联网协议入门(二)
    互联网协议入门(一)
    careercup-扩展性和存储限制10.6
    careercup-扩展性和存储限制10.4
    careercup-扩展性和存储限制10.3
    写一个函数找到给定字符串的位置
    手工删除crfclust.bdb文件
    VirtualBox 报错VERR_VD_IMAGE_READ_ONLY
    Oracle DG测试failover和后续恢复报告
    ASM的备份集在文件系统上恢复测试
  • 原文地址:https://www.cnblogs.com/toUpdating/p/10179010.html
Copyright © 2011-2022 走看看