Redis (4) of the growth path of program apes--Introduction to the string type of redis data structure

Preface
Students who have studied java should know that string mainly refers to the string type in the java language, and this does not belong to the basic data types of java. And in redis, what is the string type? What are its common usage scenarios? What are the common commands?

What is the string type of redis?

The String type consists of two parts in redis, one part is the key, which is the key, and the other part is the value, which is the value. Redis binds the key and the value, and finds the value of the value through the key.

Usage scenarios of String type

  1. Used to store data such as shared sessions and verification codes that require timeout settings
    Setex session_key 7200 session_value // Set to expire after two hours (2 * 60 * 60), in seconds
  2. Used to store json strings (serialized objects) such as commodity information, user information, etc.
    Mset key1 userinfo1 key2 userinfo2
  3. Used to set distributed lock
    setnx lockname lockvalue
  4. count
    set counter 1
    incr counter

string Commonly used commands: (redis)

  1. append key value // If the Key already exists, the APPEND command will append the data of the parameter Value to the end of the existing Value. If the Key does not exist, the APPEND command will create a new Key/Value, and the return value is the length of the new value
  2. incr/decr key //Atomic data plus/minus
  3. incrby/decrby key nb // atomic data plus/minus nb
  4. get key //get data
  5. set key value // store data, if the Key already exists, overwrite its original value
  6. strlen key // length of value
  7. setex key seconds value // Atomically complete two operations, one is to set the value of the Key to a specified string, and at the same time set the survival time (in seconds) of the Key in the Redis server.
  8. setnx key value // store value if key does not exist
  9. mget key1 [key2 …] // Get the value of key1 and key2
  10. mset key1 value1 [key2 value2 ...] //Set value1, value2

Dynamic memory allocation mechanism of Redis string type? (extended)

Strings in redis allocate memory dynamically. The internal structure implementation is similar to Java's ArrayList (dynamically expand the length of the array according to the loading factor and the actual maximum length). There is another rule: if the length of the string is less than 1M, use the doubling expansion method, and if the size exceeds 1M, expand the capacity at 1M. But if the total length of the string cannot exceed 512M.
Since redis is developed based on C language, we can use the structure (struct) in C language to describe, and the structure is named sds.
Struct SDS { T len; // Existing data length T alloc; // Array capacity Char flags; // Special flag Char[] buff; //Store string };




Why is it set up like this?

  1. alloc — reduce the complexity of array expansion
    For Java, we can use length to get the length of the array when expanding the array, but not in C language. Every time we allocate memory, we will use void *malloc(size) or void *calloc(size ) method to allocate, but obviously we need to pass in the length of the address that needs to be allocated. Therefore, this design can be expanded faster. The time complexity is O(1).
  2. Len — Ensures data integrity without truncation.
    If the string saves binary files such as pictures and videos, there may be a '0' character in the middle. Everyone knows that once the '0' character is read, it will stop reading. Therefore, the existing data length is added here to ensure the integrity of data truncation.
    In addition, it can be used together with capacity to reduce frequent memory allocation. For SDS, when appending strings (append command), the program will use alloc-len to compare whether the remaining free memory is enough to allocate the additional content, if not enough, it will naturally trigger memory reallocation, and if the remaining unused memory If there is enough space to put it down, then it will be allocated directly without memory reallocation. Its expansion strategy is that when the size of the string is less than 1M, each allocation is len * 2, that is, 100% redundancy is reserved; after it is greater than 1M, in order to avoid waste, only 1M more space is allocated, and the maximum does not exceed 512M .

  3. Flags — determine what sds structure is used
    to store data sdshdr5 structure to store data
    #define SDS_TYPE_8 1 // The first three digits of the flag are 001, indicating that the sdshdr8 structure is used to store data
    #define SDS_TYPE_16 2 // The first three digits of the flag are 010, indicating that the sdshdr16 structure is used to store data
    #define SDS_TYPE_32 3 // The first three digits of the flag are 011, indicating that the sdshdr32 structure is used to store data
    #define SDS_TYPE_64 4 // The first three digits of the flag are 100, indicating that the sdshdr64 structure is used to store data.
    In this way, the most suitable structure can be selected Store data and improve memory optimization.
    There are five kinds of sdshdr (the structure described above) in the sds.h source code in Redis, which are as follows (the following are all source codes):
struct __attribute__ ((__packed__)) sdshdr5 {
    
    
    unsigned char flags; /* 3 lsb of type, and 5 msb of string length */
    char buf[];
};
struct __attribute__ ((__packed__)) sdshdr8 {
    
    
    uint8_t len; /* used */
    uint8_t alloc; /* excluding the header and null terminator */
    unsigned char flags; /* 3 lsb of type, 5 unused bits */
    char buf[];
};
struct __attribute__ ((__packed__)) sdshdr16 {
    
    
    uint16_t len; /* used */
    uint16_t alloc; /* excluding the header and null terminator */
    unsigned char flags; /* 3 lsb of type, 5 unused bits */
    char buf[];
};
struct __attribute__ ((__packed__)) sdshdr32 {
    
    
    uint32_t len; /* used */
    uint32_t alloc; /* excluding the header and null terminator */
    unsigned char flags; /* 3 lsb of type, 5 unused bits */
    char buf[];
};
struct __attribute__ ((__packed__)) sdshdr64 {
    
    
    uint64_t len; /* used */
    uint64_t alloc; /* excluding the header and null terminator */
    unsigned char flags; /* 3 lsb of type, 5 unused bits */
    char buf[];
};

The memory model is as follows:
insert image description here

Note: where len represents the actual length of the array and alloc represents the length of the array allocation. The first type cannot automatically expand the length of the array due to the absence of len and alloc. Once the pre-allocated address is used up, the memory space must be reallocated and completed. Data replication consumes a lot of performance, so it is rarely used.

more links

Redis installation https://blog.csdn.net/qq_31236027/article/details/121879741
redis introduction https://blog.csdn.net/qq_31236027/article/details/121879604
redis data structure introduction https://blog.csdn. net/qq_31236027/article/details/121894713

Guess you like

Origin blog.csdn.net/qq_31236027/article/details/122016881