• RedisObject


    RedisObject结构

    typedef struct redisObject {
        // 类型
        unsigned type:4;
        // 编码
        unsigned encoding:4;
        // 对象最后一次被访问的时间
        unsigned lru:REDIS_LRU_BITS; /* lru time (relative to server.lruclock) */
        // 引用计数
        int refcount;
        // 指向实际值的指针
        void *ptr;
    } robj;
    

    type类型

    #define OBJ_STRING 0
    #define OBJ_LIST 1
    #define OBJ_SET 2
    #define OBJ_ZSET 3
    #define OBJ_HASH 4
    

    encoding类型

    encoding 表示 ptr 指向的具体数据结构,即这个对象使用了什么数据结构作为底层实现。

    #define OBJ_ENCODING_RAW 0     /* Raw representation */
    #define OBJ_ENCODING_INT 1     /* Encoded as integer */
    #define OBJ_ENCODING_HT 2      /* Encoded as hash table */
    #define OBJ_ENCODING_ZIPMAP 3  /* Encoded as zipmap */
    #define OBJ_ENCODING_LINKEDLIST 4 /* Encoded as regular linked list */
    #define OBJ_ENCODING_ZIPLIST 5 /* Encoded as ziplist */
    #define OBJ_ENCODING_INTSET 6  /* Encoded as intset */
    #define OBJ_ENCODING_SKIPLIST 7  /* Encoded as skiplist */
    #define OBJ_ENCODING_EMBSTR 8  /* Embedded sds string encoding */  
    #define OBJ_ENCODING_QUICKLIST 9 /* Encoded as linked list of ziplists */
    

    string

    • 如果一个字符串对象保存的是整数值,并且这个整数值可以用 long 类型标识,那么字符串对象会讲整数值保存在 ptr 属性中,并将 encoding 设置为 int。
    • 如果字符串对象保存的是一个字符串值,并且这个字符串的长度大于 32 字节,那么字符串对象将使用SDS来保存这个字符串值,并将对象的编码设置为 raw。
    • 如果字符串对象保存的是一个字符串值,并且这个字符串的长度小于等于 32 字节,那么字符串对象将使用 embstr 编码的方式来保存这个字符串。

    embstr

    如果字符串对象保存的是一个字符串值, 并且这个字符串值的长度小于等于 39 字节, 那么字符串对象将使用 embstr 编码的方式来保存这个字符串值

    embstr是字符串长度小于32字节的字符串编码类型,其中object的ptr与sds的数据地址相邻。由于redisObject的头结构占16个字节,sds的头结构为3字节,加上字符串末尾的字节,所有embstr的最大存储长度为64-16-3-1=44字节(使用jemalloc或tcmalloc分配的内存大小最大64字节)

    为什么还会有 embstr 的编码方式呢?

    • embstr 编码将创建字符串对象所需的内存分配次数从 raw 编码的两次降低为一次。
    • 释放 embstr 编码的字符串对象只需要调用一次内存释放函数,而释放 raw 编码的字符串对象需要调用两次内存释放函数。
    • 因为 embstr 编码的字符串对象的所有数据都保存在一块连续的内存里面,所以这种编码的字符串对象比起 raw ,编码的字符串对象能够更好地利用缓存带来的优势。

    hash

    • 当哈希对象保存的键值对数量小于 512,并且所有键值对的长度都小于 64 字节时,使用压缩列表存储
    • 否则使用 hashtable 存储

    list

    • 当列表的长度小于 512,并且所有元素的长度都小于 64 字节时,使用压缩列表存储
    • 否则使用 linkedlist 存储

    set

    • 当集合的长度小于 512,并且所有元素都是整数时,使用整数集合存储
    • 否则使用 hashtable 存储

    zset

    • 当有序集合的长度小于 128,并且所有元素的长度都小于 64 字节时,使用压缩列表存储
    • 否则使用 dict、skiplist 存储

    参考

    1. Redis学习笔记:对象
    2. Redis redisObject
  • 相关阅读:
    思维导图形式带你读完《大型网站技术架构》中
    思维导图形式带你读完《大型网站技术架构》上
    淘淘商城项目补充(2)商品上架和下架功能实现
    淘淘商城项目补充(1)批量删除商品功能实现
    商城项目(ssm+dubbo+nginx+mysql统合项目)总结(3)
    阿里Java研发工程师实习面经,附面试技巧
    商城项目(ssm+dubbo+nginx+mysql统合项目)总结(2)
    商城项目(ssm+dubbo+nginx+mysql统合项目)总结(1)
    高性能优秀的服务框架-dubbo介绍
    回溯算法_01背包问题_Java实现
  • 原文地址:https://www.cnblogs.com/weiweng/p/12743607.html
Copyright © 2020-2023  润新知