One, foreword

Redis provides five data types: String, Hash, List, Set, and Zset. Understanding the characteristics of each data type is important for the development and operation of Redis.

The original resolution

The list in Redis is a data type that we often use. It can be applied to many scenarios depending on how it is used.

2. Operation commands

List data types in Redis:

The command describe usage
LPUSH 1. Insert one or more values into the key header of the list

2. If there are multiple values, insert each value into the table header from left to right

3. If the key does not exist, an empty list will be created and LPUSH will be performed

4. The key exists but is not a list type
LPUSH key value [value …]
LPUSHX 1. Insert the value value into the head of the list key if and only if the key exists and is a list

2. LPUSHX does nothing if key does not exist
LPUSHX key value
LPOP 1. Remove and return the header element of the list key LPOP key
LRANGE 1. Return the element in the list key within the range specified by the offsets start and stop

2. Start and stop both start and stop with 0 bits

3. Use a negative subscript, -1 for the last element in the list, -2 for the next-to-last element, and so on

4. If start is greater than the maximum index of the list, an empty list is returned

5. Stop is greater than the maximum list subscript, stop= the maximum list subscript
LRANGE key start stop
LREM 1. Remove elements equal to value from the list based on the value of count

2. If count>0 is searched from beginning to end, the number of elements equal to value is count

3. If count<0, remove elements equal to value from the end of the search

4. Count =0 removes all elements equal to value in the table
LREM key count value
LSET 1. Set the value of the element whose key subscript is index to value

2. An error is returned when the index parameter is out of range or an empty list is LSET
LSET key index value
LINDEX 1. Return the index element in the key list LINDEX key index
LINSERT 1. Insert the value value into the list key, either before or after pivot

2. When pivot does not exist in the list key, no operation is performed

3. If the key does not exist, no operation is performed
LINSERT key BEFORE
LLEN 1. Return the length of the list key

2. If the key does not exist, 0 is returned
LLEN key
LTRIM 1. Prune a list so that only elements within the specified range are returned LTRIM key start stop
RPOP 1. Remove and return the last element of the list key RPOP key
RPOPLPUSH In one atomic time, two actions are performed:

1. Pop up the last element in the list source and return it to the client

2. Insert the source popup element to desination as the head element of the destination list
RPOPLPUSH source destination
RPUSH 1. Insert one or more values value to the end of the key list RPUSH key value [value …]
RPUSHX 1. Insert value at the end of the list key if and only if the key exists and is a list

2. Key does not exist, RPUSHX does nothing
RPUSHX key value

Practice: Don’t be lazy. Try it out

Three, application scenarios

  • 1, lpush+lpop=Stack
  • Lpush +rpop=Queue
  • 3, LPUSH + Ltrim =Capped Collection
  • Lpush + brPOP =Message Queue
  • 5. Leaderboards, latest data lists, etc

Fourth, the underlying analysis

As the structure diagram shows, there are two implementations of the List type: for example, create the List object numbers

1. List objects implemented using ziplist

The structure is as follows:

A list object implemented using a linkedList

The structure is as follows:

Five, question thinking

What is the structure of a compressed list and a double-entailed list?

1. Ziplist

Ziplist is developed by Redis to save memory. It is a sequential data structure composed of a series of consecutively encoded memory blocks. A ziplist can contain any number of entries, and each node can hold a byte array or an integer value.

The structure is as follows:

The structure of each node in the compressed list is as follows:

1) previous_entry_ength: Records the length of the previous byte in the compressed list, in bytes. The length of previous_entry_ength can be 1 byte or 5 bytes: if the length of the previous node is less than 254 bytes, the previous_entry_ength attribute is 1 byte, and the length of the previous node is stored in that one byte. If the length of the previous node is greater than or equal to 254, the previous_entry_ength attribute is 5 bytes long, where the first byte of the attribute is set to 0xFE (decimal 254) and the next four bytes are used to hold the length of the previous node. Using this principle, the starting position of the previous node can be obtained by subtracting the length of the current node. The compressed list can be traversed from the tail to the head, which effectively reduces the waste of memory. Encoding: Records the type and length of data stored in the content property of the node. 3) Content: Holds the value of the node, which can be a byte array or an integer. The type and length of the value are determined by the encoding property of the node.

2. Linkedlist

Linked list is a commonly used data structure. There is no built-in implementation of such data structure in C language, so Redis builds the implementation of linked list by itself. List node definitions:

typedef  struct listNode{
       // The front node
       struct listNode *prev;
       // back node
       struct listNode *next;
       // Node value
       void *value;  
}listNode
Copy the code

Multiple ListNodes can form a double-ended list using prev and next Pointers. The structure is as follows:

Redis also provides data structures for manipulating linked lists:

typedef struct list{
     // Table header node
     listNode *head;
     // Table end node
     listNode *tail;
     // The number of nodes in the linked list
     unsigned long len;
     // Node value copy function
     void (*free) (void *ptr);
     // Node value release function
     void (*free) (void *ptr);
     // Node value comparison function
     int (*match) (void *ptr,void *key);
}list;
Copy the code

The list structure provides the head pointer, tail pointer, and len length counter for the list. The dUP, free, and match members are the type specific functions needed to implement polymorphic lists.

Redis linked list implementation features:

  • Double-ended: Linked list nodes have prev and next Pointers, and the complexity of obtaining a node’s pre-node and post-node is O(1).
  • Acyclic: The prev pointer on the head node and the next pointer on the tail node point to NULL, and access to the linked list ends at NULL.
  • With head and tail Pointers: With the head and tail Pointers of the list structure, the complexity of obtaining the head and tail of the list is O(1).
  • List length counter: The program uses the len attribute of the list structure to count the list nodes held by the list. The complexity of obtaining the number of nodes in the list is O(1).
  • Polymorphic: Linked list nodes use void* Pointers to hold node values, and use the dUP, free, and match attributes of the list structure to set type-specific functions for node values, so linked lists can be used to hold various types of values.

Question: When will Redis lists be ziplist encoded and when will LinkedList encoded?

More on that in the next section…