“This is my 36th day of participating in the First Challenge 2022. For details: First Challenge 2022.”

String object

The three encodings of a character object can be int, raw, or embstr.

  1. If a string object holds an integer value that can be represented by type long, the string will store the integer value in the PTR property value of the string object structure, and the string object’s encoding is set to int.

  2. If a string holds a character value and the string length is less than or equal to 32 bytes, the string uses the embSTR encoding to hold the string value.

  3. Embstr encoding is an optimized encoding for holding short strings. This encoding, like raw encoding, uses the SDSHDR structure in redisObject to represent string objects. Whereas raw calls the memory ratio allocation function twice to create the redisObject and SDSHDR structures, EMbSTR calls the memory once to allocate a contiguous space containing the redisObject and SDSHDR structures in turn

Int encodes the following string:

Embstr encodes the following characters:

The raw encoded characters are as follows:Here are all the types of redisObject:

char *strEncoding(int encoding) { switch(encoding) { case OBJ_ENCODING_RAW: return "raw"; case OBJ_ENCODING_INT: return "int"; case OBJ_ENCODING_HT: return "hashtable"; case OBJ_ENCODING_QUICKLIST: return "quicklist"; case OBJ_ENCODING_ZIPLIST: return "ziplist"; case OBJ_ENCODING_LISTPACK: return "listpack"; case OBJ_ENCODING_INTSET: return "intset"; case OBJ_ENCODING_SKIPLIST: return "skiplist"; case OBJ_ENCODING_EMBSTR: return "embstr"; case OBJ_ENCODING_STREAM: return "stream"; default: return "unknown"; }}Copy the code

We mainly analyze OBJ_ENCODING_INT, OBJ_ENCODING_RAW and OBJ_ENCODING_EMBSTR together

Int (OBJ_ENCODING_INT)

A length less than 20 ensures that within a long integer, 2^64 takes up exactly 20 bits and is a numeric string.

This is a long integer that covers all types of longs.

Embstr (OBJ_ENCODING_EMBSTR)

The length is less than or equal to 44 characters (including floating-point numbers). 44 bytes are only needed to accommodate the jemalloc allocation of 64K arena

/* Create a string object with EMBSTR encoding if it is smaller than
 * OBJ_ENCODING_EMBSTR_SIZE_LIMIT, otherwise the RAW encoding is
 * used.
 *
 * The current limit of 44 is chosen so that the biggest string object
 * we allocate as EMBSTR will still fit into the 64 byte arena of jemalloc. */
#define OBJ_ENCODING_EMBSTR_SIZE_LIMIT 44
robj *createStringObject(const char *ptr, size_t len) {
    if (len <= OBJ_ENCODING_EMBSTR_SIZE_LIMIT)
        return createEmbeddedStringObject(ptr,len);
    else
        return createRawStringObject(ptr,len);
}
Copy the code

This can be interpreted as a short string, not a 20-bit integer.

Raw (OBJ_ENCODING_RAW)

Strings larger than 44 bytes (including floating-point numbers) are simply any other string, or string floating-point numbers. Detailed comparisons will be made below.

Comparison between RAW and EMbstr

Raw and EMbstr are compared as follows:

type The characteristics of advantages disadvantages
embstr 1. Memory space is allocated only once, so ROBj and SDS are continuous; 2. Read only; 3. When the Embstr string needs to be modified, it is converted to RAW and remains raw thereafter 1. Create and delete only once. 2. Fast search speed 1. Reallocation involves robj and the entire SDS object, so embstr is read-only
raw 1. Robj and SDS are discontinuous; 2. You can modify it

Embstr is created as follows:

RedisObject object creation:

Modifying a string with the append command changes the underlying type of the string:

Through this experiment, two points are proved:

  1. The floating point number redis is stored with embstr.
  2. Embstr will be converted to raw storage if there is an append operation.

Underlying code (embstr converting raw) :

Redis string qualification

Redis strings can be no longer than 512 megabytes, which is usually difficult to achieve during development, unless you want to store something like Base64, which is already large by default.

Static int checkStringLength(client *c, long long size) {if (! (c->flags & CLIENT_MASTER) && size > server.proto_max_bulk_len) { addReplyError(c,"string exceeds maximum allowed size (proto-max-bulk-len)"); return C_ERR; } return C_OK; }Copy the code

This length can be set in redis.config. Set key proto-max-bulk-len default value: 512mb. As shown below:

String Usage Scenarios

  • Cache function: mysql for persistent data storage, Redis for a small amount of hot data cache;
  • Counter: such as the number of likes, the number of videos played;
  • Traffic limiting: see Distributed traffic limiting based on Redis.

Using commands and other practices can be referenced in my previous articles, which are not covered here:

  • Redis core data type

Common operations

Reference documentation

  • Redis Design and Implementation, Huang Jianhong