zoukankan      html  css  js  c++  java
  • Redis中的对象

    Redis中的每个对象都由一个redisObject结构表示,该结构中和保存数据有关的三个属性分别是typeencodingptr

    typedef struct redisObject {
        unsigned type:4; // 类型
        unsigned encoding:4;// 编码
        unsigned lru:LRU_BITS; /* LRU time (relative to global lru_clock) or
                                * LFU data (least significant 8 bits frequency
                                * and most significant 16 bits access time). */
        int refcount;
        void *ptr;// 指向底层实现数据结构的指针
    } robj;
    

    1. 类型

    Redis一共有5种类型,其中键值总是一个字符串对象,而可以是5中类型中的任意一种。可以通过TYPE命令来查看对应的的类型

    # 键为字符串对象,值为字符串对象
    redis> SET msg "hello world"
    OK
    redis> TYPE msg
    string
    # 键为字符串对象,值为列表对象
    redis> RPUSH numbers 1 3 5
    (integer)6
    redis> TYPE numbers
    list
    
    不同类型值对象的TYPE命令输出
    对象类型 对象type属性值 TYPE命令的输出
    字符串 REDIS_STRING "string"
    列表 REDIS_LIST "list"
    哈希 REDIS_HASH "hash"
    集合 REDIS_SET "set"
    有序集合 REDIS_ZSET "zset"

    2. 编码

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

    redis> SET msg "hello world"
    OK
    redis> OBJECT ENCODING msg
    "embstr" // msg为embstr类型
    redis> SET story "long long long long long long long ago ..."
    OK
    redis> OBJECT ENCODING msg
    "raw" // msg从embstr类型变成raw类型
    redis> SADD numbers 1 3 5
    (integer)3
    redis> OBJECT ENCODING numbers
    "intset" // numbers为intset类型
    redis> SADD numbers "seven"
    (integer)1
    redis> OBJECT ENCODING numbers
    "hashtable" // numbers从intset类型变成hashtable类型
    
    不同类型和编码的对象
    类型 编码常量 底层数据结构
    REDIS_STRING REDIS_ENCODING_INT 整数
    REDIS_STRING REDIS_ENCODING_IEMBSTR embstr编码的简单动态字符串
    REDIS_STRING REDIS_ENCODING_RAW 简单动态字符串
    REDIS_LIST REDIS_ENCODING_ZIPLIST 压缩列表
    REDIS_LIST REDIS_ENCODING_LINKEDLIST 双端链表
    REDIS_HASH REDIS_ENCODING_ZIPLIST 压缩列表
    REDIS_HASH REDIS_ENCODING_HT 字典
    REDIS_SET REDIS_ENCODING_INTSET 整数集合
    REDIS_SET REDIS_ENCODING_HT 字典
    REDIS_ZSET REDIS_ENCODING_ZIPLIST 压缩列表
    REDIS_ZSET REDIS_ENCODING_SKIPLIST 跳跃表
    OBJECT ENCODING对不同类型编码的输出
    编码常量 OBJECT ENCODING命令输出
    REDIS_ENCODING_INT "int"
    REDIS_ENCODING_IEMBSTR "embstr"
    REDIS_ENCODING_RAW "raw"
    REDIS_ENCODING_HT "hashtable"
    REDIS_ENCODING_LINKEDLIST "linkedlist"
    REDIS_ENCODING_ZIPLIST "ziplist"
    REDIS_ENCODING_INTSET "intset"
    REDIS_ENCODING_SKIPLIST "skiplist"

    3. 对象底层数据结构

    在Redis中为了节省空间,对象的编码是会发生转化,底层的数据结构也会随着发生变化。

    • 字符串对象编码的转换规则

      1. 如果一个字符串对象保存的是整数值,并且这个值可以用long类型来表示,那么字符串对象会将整数值保存在对象结构ptr属性里面,并将字符串对象的属性设置为int
      2. 如果字符串对象保存的是一个字符串值,并且长度小于39字节,那么字符串对象将使用embstr编码
      3. 对于 int编码的字符串对象来说,如果将值修改成字符串,那么字符串对象的编码将从int变为raw
      4. 对于 embstr编码的字符串对象来说,如果字符串的长度大于39字节,那么字符串对象的编码将从embstr变为raw
    • 列表对象编码的转换规则

      1. 当列表对象保存的所有字符串元素的长度都小于64字节,并且保存的元素数量小于512个,对象将使用ziplist编码
      2. 如果对象不满足ziplist编码的条件,对象将使用linkedlist编码
    • 哈希对象编码的转换规则

      1. 当哈希对象保存的所有键和值的字符串长度都小于64字节,并且键值对数量小于512个,对象将使用ziplist编码
      2. 如果对象不满足ziplist编码的条件,对象将使用hashtable编码
    • 集合对象编码的转换规则

      1. 当集合对象保存的所有元素都是整数值,并且元素数量小于512个,对象将使用inset编码
      2. 如果对象不满足inset编码的条件,对象将使用hashtable编码
    • 有序集合对象编码的转换规则

      1. 当集合对象中保存的元素数量小于128个,并且所有元素成员的长度都小于64字节,对象将使用ziplist编码
      2. 如果对象不满足ziplist编码的条件,对象将使用skiplist编码

    4. 对象类型检查、回收、共享和空转时长

    • 服务器在执行某些命令之前,会先检查给定键的类型能否执行指定的命令,而检查一个键的类型就是检查键的值对象的类型

    • Redis的对象带有引用计数实现的内存回收机制,当一个对象不再被使用时,该对象锁占用的内存就会被自动释放

    • Redis会自动共享值为0~9999的字符串对象

    • 每个对象会记录自己的最后一次被访问的时间,这个时间可以用于计算对象的空转时间。当回收算法为volatile-lru或者allkeys-lru,那么当服务器占用的内存超过了maxmemory选项所设置的上限时,空转时间较高的那部分键会被服务器优先释放,从而回收内存

  • 相关阅读:
    Proj THUDBFuzz Paper Reading: The Art, Science, and Engineering of Fuzzing: A Survey
    Proj THUDBFuzz Paper Reading: A systematic review of fuzzing based on machine learning techniques
    9.3 付费代理的使用
    11.1 Charles 的使用
    第十一章 APP 的爬取
    10.2 Cookies 池的搭建
    10.1 模拟登录并爬取 GitHub
    11.5 Appium 爬取微信朋友圈
    11.4 Appium 的基本使用
    11.3 mitmdump 爬取 “得到” App 电子书信息
  • 原文地址:https://www.cnblogs.com/pinxiong/p/13288081.html
Copyright © 2011-2022 走看看