zoukankan      html  css  js  c++  java
  • 对象系统

    对象系统

    1. Redis使用对象来表示数据库中的键和值
    2. 每种对象都用到了至少一种数据结构:动态字符串、链表、字典、跳跃表、整数集合、压缩列表
    3. 针对不同的使用场景,为对象设置多种不同的数据结构实现,优化对象在不同场景下的使用效率
    4. 基于引用计数技术的 内存回收机制对象共享机制
    5. 对象带有访问时间记录信息,

    定义

    // 对象类型
    // 字符串对象
    #define OBJ_STRING 0    
    // 列表对象
    #define OBJ_LIST 1      
    // 集合对象
    #define OBJ_SET 2       
    // 有序集合对象
    #define OBJ_ZSET 3      
    // 哈希对象
    #define OBJ_HASH 4      
    
    // 对象编码类型
    // 简单动态字符串
    #define OBJ_ENCODING_RAW 0     
    // long类型的整数
    #define OBJ_ENCODING_INT 1     
    // 字典
    #define OBJ_ENCODING_HT 2      
    #define OBJ_ENCODING_ZIPMAP 3  
    // 双端链表
    #define OBJ_ENCODING_LINKEDLIST 4 
    // 压缩列表
    #define OBJ_ENCODING_ZIPLIST 5 
    // 整数
    #define OBJ_ENCODING_INTSET 6  
    // 跳跃表
    #define OBJ_ENCODING_SKIPLIST 7  
    // embstr编码的简单动态字符串
    #define OBJ_ENCODING_EMBSTR 8  
    // 压缩链表
    #define OBJ_ENCODING_QUICKLIST 9 
    // 流
    #define OBJ_ENCODING_STREAM 10 
    
    /**
     * 对象redisObject数据结构
     * Redis 存储的 value 数据都是用 redisObject 来封装的
     * 包括 string,hash,list,set,zset  在内的所有数据类型
     */
    typedef struct redisObject {
        /**
         * 对象类型:表示当前对象使用的数据类型,
         * Redis主要支持5种数据类型:string,hash,list,set,zset。
         * 可以使用type {key}命令查看对象所属类型,
         * type命令返回的是值对象类型,键都是string类型。
         */
        unsigned type:4;
    
        // 
        /**
         * 编码类型:ptr指针所指向对象的底层实现数据结构类型,即当前对象使用了什么数据结构作为对象的底层实现
         * 表示Redis内部编码类型,encoding在Redis内部使用,
         * 代表当前对象内部采用哪种数据结构实现。
         * 理解Redis内部编码方式对于优化内存非常重要 ,
         * 同一个对象采用不同的编码实现内存占用存在明显差异,
         */
        unsigned encoding:4;
        
        // 缓存策略数据
        // 空转时长(idletime) = 当前时间 - lru属性时间
        // LRU是Least Recently Used的缩写,即最近最少使用,是一种常用的页面置换算法,选择最近最久未使用的页面予以淘汰
        // 该算法赋予每个页面一个访问时间字段,用来记录一个页面自上次被访问以来所经历的时间 idletime,当须淘汰一个页面时,选择现有页面中其 idletime 值最大的
    
        /**
         * 记录对象最后一次被访问的时间,
         * 当配置了maxmemory 和 maxmemory-policy=volatile-lru | allkeys-lru 时,辅助LRU算法释放高空转时长键,回收内存
         */
        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). */
        
        // LFU是Least Frequently Used的缩写,即最近最不经常使用,是一种常用的页面置换算法,选择引用计数最小的页面予以淘汰
        // 该算法赋予每个页面一个引用计数字段,用来记录一个页面使用次数 refcount,当须淘汰一个页面时,选择现有页面中其 refcount 值最小的
        
        /**
         * 引用计数:记录当前对象被引用的次数,用于通过引用次数回收内存,
         * 当refcount=0时,可以安全回收当前对象空间。
         * 使用 object refcount {key} 获取当前对象引用。
         */
        int refcount;
    
        /**
         * 指底层实现数据结构的指针:保存实际的数据
         * 与对象的数据内容相关,如果是整数直接存储数据,否则表示指向数据的指针。
         * Redis在3.0 之后对值对象是字符串且长度 <=39 字节的数据,
         * 内部编码为 embstr 类型,字符串 sds 和 redisObject 一起分配,从而只要一次内存操作。
         * 因此在高并发的场景尽量是我们的字符串保持 39 字节内,
         * 减少创建redisObject内存分配次数从而提高性能。
         */
        void *ptr;
    } robj;
    
    

    TYPE 命令

    查看数据库键【对应的值对象】的类型

    OBJECT ENCODING 命令

    查看数据库键的【值对象】的编码

    OBJECT REFCOUNT 命令

    查看数据库键的【值对象】的引用计数

    OBJECT IDLETIME 命令

    查看数据库键的空转时长,不会修改值对象的lru属性

    源码阅读

    1. 文件:src/server.h
    只言片语任我说,提笔句句无需忖。落笔不知寄何人,唯有邀友共斟酌。
  • 相关阅读:
    设计模式
    工厂方法模式
    简单工厂模式
    tornado自定义Form组件
    tornado
    Tornado框架的知识系列
    Linux基本命令
    day2
    day1
    使用cp复制文件夹却不能打开
  • 原文地址:https://www.cnblogs.com/phonecom/p/15090762.html
Copyright © 2011-2022 走看看