RedisObject object

In Redis Server, all keys and values are encapsulated in a unified structure called RedisObject, or robj, defined in server.h

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;
Copy the code
  • type: occupies four bits, indicating the data type, which is defined inserver.hIn the
/*----------------------------------------------------------------------------- * Data types * -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - * /

/* A redis object, that is a type able to hold a string / list / set */

/* The actual Redis Object */
#define OBJ_STRING 0    /* String object. */
#define OBJ_LIST 1      /* List object. */
#define OBJ_SET 2       /* Set object. */
#define OBJ_ZSET 3      /* Sorted set object. */
#define OBJ_HASH 4      /* Hash object. */

/* The "module" object type is a special one that signals that the object * is one directly managed by a Redis module. In this case the value points * to a moduleValue struct, which contains the object value (which is only * handled by the module itself) and the RedisModuleType struct which lists * function pointers in order to serialize, deserialize, AOF-rewrite and * free the object. * * Inside the RDB file, module types are encoded as OBJ_MODULE followed * by a 64 bit module type ID, which has a 54 bits module-specific signature * in order to dispatch the loading to the right module, plus a 10 bits * encoding version. */
#define OBJ_MODULE 5    /* Module object. */
#define OBJ_STREAM 6    /* Stream object. */
Copy the code

When the type {key} command is used on the client, OBJ_MODULE will be replaced by OBJ_* in the db. C# typeCommand method

To query the implementation of a command, go to the server.c file and view redisCommandTable. The command table defines all command names and the implementation method names

  • encodingRedis in order to optimize memory, even if the same type, there may be different encoding, use the commandobject encoding {key}You can view the internal encoding of value. The encoding supported by Redis is also defined in theserver.hIn the
/* Objects encoding. Some kind of objects like Strings and Hashes can be * internally represented in multiple ways. The 'encoding' field of the object * is set to one of this fields for this object. */
#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 /* No longer used: old list encoding. */
#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 */
#define OBJ_ENCODING_STREAM 10 /* Encoded as a radix tree of listpacks */
Copy the code
  • lru: occupies 24 bits and represents the last time an object was accessed. Although this variable is called LRU, it can also represent the access frequency information required by the LFU. useobject idletime {key}View the idle time of the key, in seconds
#define LRU_BITS 24
Copy the code

This field has 24 bits. When creating a RedisObject, if maxmemory-policy is configured and is related to LFU policy, this field is divided into 16-bit minute-level timestamp and 8-bit access frequency

  • refcount: 4 bytes, reference count, how many times the robj is referenced, used to free objects, memory reclamation. useobject refcount keyCheck the number of times the key is referenced
  • PTR: An 8-byte pointer to specific data

Shared Object Pool

Since the RedisObject itself takes up at least 16 bytes and would take up more memory than the data itself to store numbers, Redis internally creates a pool of long integers [0-9999]

// server.h
#define OBJ_SHARED_INTEGERS 10000
#define OBJ_SHARED_REFCOUNT INT_MAX

// server.c
 for (j = 0; j < OBJ_SHARED_INTEGERS; j++) {
        shared.integers[j] =
            makeObjectShared(createObject(OBJ_STRING,(void(*)long)j));
        shared.integers[j]->encoding = OBJ_ENCODING_INT;
    }
    
// object.c
robj *makeObjectShared(robj *o) {
    serverAssert(o->refcount == 1);
    o->refcount = OBJ_SHARED_REFCOUNT;
    return o;
}
Copy the code

Redis disallows the use of shared object pools when maxMemory is set and lRU-related elimination policies are enabled. Since THE LRU needs to get the last access time of the object in order to eliminate the data, the last access time of each object is stored in the LRU field of the RedisObject. If the RedisObject is shared, the LRU is also shared, so there is no way to get the last access time of each object.