I. Overview:
In Redis, the List type is a string linked List sorted by insertion order. Like the common linked list in the data structure, we can add new elements in the header (left) and tail (right. If the key does not exist during insertion, Redis creates a new linked list for the key. In contrast, if all elements in the linked list are removed, the key will also be deleted from the database. The maximum number of elements in a List is 4294967295.
From the perspective of element insertion and deletion efficiency, If we insert or delete elements at both ends of the linked list, this will be very efficient, this operation can be completed within the constant time even if millions of records have been stored in the linked list. However, it should be noted that if the element insertion or deletion operation acts on the center of the linked list, it will be very inefficient. It is believed that this is not difficult for developers with a sound data structure.
Ii. Related command list:
Command prototype |
Time Complexity |
Command description |
Return Value |
LPUSHKey value [value...] |
O (1) |
Insert all Values in the header of the List Value associated with the specified Key. If the Key does not exist, this command will create an empty linked list associated with the Key before insertion, and then insert the data from the head of the linked list. If the Value of the key is not of the linked list type, the command returns an error message. |
The number of elements in the inserted linked list. |
LPUSHXKey value |
O (1) |
Only when the Key specified in the parameter exists will the command Insert the Value given in the parameter in the header of the associated List Value. Otherwise, no operation will occur. |
The number of elements in the inserted linked list. |
LRANGEKey start stop |
O (S + N) |
In time complexity, S is the offset expressed by the start parameter, and N represents the number of elements. The start and end parameters of this command are both 0-based. 0 indicates the first element of the chain table header (leftmost. The start value can also be a negative value.-1 indicates the last element in the linked list, that is, the tail element.-2 indicates the second to the last and so on. When this command is used to obtain elements, the elements at the start and end locations will also be taken out. If the start value is greater than the number of elements in the linked list, the empty linked list will be returned. If the end value is greater than the number of elements, this command obtains all the elements from the start (including start) and linked list. |
Returns the list of elements in the specified range. |
LPOPKey |
O (1) |
The first element in the linked list associated with the specified Key, that is, the Header element, is displayed ,. If the Key is not saved, nil is returned. |
The element of the linked list header. |
LLENKey |
O (1) |
Returns the number of elements in the linked list associated with the specified Key. If the Key does not exist, 0 is returned. If the type of the Value associated with the Key is not a linked list, the related error message is returned. |
The number of elements in the linked list. |
LREMKey count value |
O (N) |
In time complexity, N indicates the number of elements in the linked list. In the linked list associated with the specified Key, delete the elements whose previous count value is equal to value. If count is greater than 0, it is traversed from the beginning to the end and deleted. If count is smaller than 0, it is traversed and deleted from the end. If count is equal to 0, all elements equal to value in the linked list are deleted. If the specified Key does not exist, 0 is returned directly. |
Returns the number of deleted elements. |
LSETKey index value |
O (N) |
In time complexity, N indicates the number of elements in the linked list. However, when you set the header or tail element, the time complexity is O (1 ). Set the value of the specified position in the linked list to a new value. 0 indicates the first element, that is, the Header element, and-1 indicates the tail element. If the Index value exceeds the number range of elements in the linked list, this command returns related error information. |
|
LINDEXKey index |
O (N) |
In time complexity, N indicates the number of elements to be traversed when this element is found. For header or tail elements, the time complexity is O (1 ). This command returns the element of the specified position (index) in the linked list. The index is 0-based, indicating the Header element. If the index is-1, it indicates the tail element. If the linked list is not associated with the Key, the command returns the relevant error message. |
Returns the requested element. If the index is out of the range, nil is returned. |
LTRIMKey start stop |
O (N) |
N indicates the number of deleted elements. This command retains only the elements within the specified range to ensure that the number of elements in the link is relatively constant. The start and stop parameters are both 0-based. 0 indicates the Header element. Like other commands, start and stop can also be negative values.-1 indicates the tail element. If start is greater than the end of the linked list, or start is greater than stop, an error is returned, but an empty linked list is returned, and the Key is also deleted. If stop is greater than the number of elements, all elements remaining from start are retained. |
|
LINSERTKey BEFORE | AFTER each value |
O (N) |
In time complexity, N indicates the number of elements that need to be traversed before the element 'struct' is found. This means that if the operator is at the head or tail of the linked list, the time complexity of this command is O (1 ). The function of this command is to insert the element value in the parameter before or after the values element. If the Key does not exist, this command will not perform any operations. If the Value type associated with the Key is not a linked list, related error messages are returned. |
Number of elements in the linked list after successful insertion. If no marker is found,-1 is returned. If the key does not exist, 0 is returned. |
RPUSHKey value [value...] |
O (1) |
Insert all Values given in the parameter at the end of the List Value associated with the specified Key. If the Key does not exist, this command will create an empty linked list associated with the Key before insertion, and then insert the data from the end of the linked list. If the Value of the key is not of the linked list type, the command returns an error message. |
The number of elements in the inserted linked list. |
RPUSHXKey value |
O (1) |
Only when the Key specified in the parameter exists will the command Insert the Value given in the parameter at the end of the associated List Value. Otherwise, no operation will occur. |
The number of elements in the inserted linked list. |
RPOPKey |
O (1) |
Returns the last element in the linked list associated with the specified Key, that is, the tail element ,. If the Key is not saved, nil is returned. |
Elements at the end of the linked list. |
RPOPLPUSHSource destination |
O (1) |
An atomic element pops up from the end of the linked list associated with the source key, and then inserts the pop-up element into the header of the linked list associated with the destination key. If the source key does not exist, this command returns nil without any other operations. If source and destination are the same key, it is equivalent to atomically moving the tail elements in the associated linked list to the head of the linked list. |
Returns the pop-up and inserted elements. |
Iii. Command example:
1. LPUSH/LPUSHX/LRANGE:
/>Redis-cli # Start the redis client tool at a Shell prompt.
Redis 127.0.0.1: 6379>Del mykey
(Integer) 1
# The mykey key does not exist. This command creates the key and its associated List, and then inserts the values in the parameter from left to right.
Redis 127.0.0.1: 6379>Lpush mykey a B c d
(Integer) 4
# Take the three elements from position 0 to position 2.
Redis 127.0.0.1: 6379>Lrange mykey 0 2
1) "d"
2) "c"
3) "B"
# Retrieve all elements in the linked list. 0 indicates the first element, and-1 indicates the last element.
Redis 127.0.0.1: 6379>Lrange mykey 0-1
1) "d"
2) "c"
3) "B"
4) ""
# The mykey2 key does not exist at this time, so this command will not perform any operation, and its return value is 0.
Redis 127.0.0.1: 6379>Lpushx mykey2 e
(Integer) 0
# You can see that mykey2 is not associated with any List Value.
Redis 127.0.0.1: 6379>Lrange mykey2 0-1
(Empty list or set)
# The mykey key already exists. Therefore, the command is successfully inserted and the current number of elements in the linked list is returned.
Redis 127.0.0.1: 6379>Lpushx mykey e
(Integer) 5
# Obtain the Header element of the List Value of the key.
Redis 127.0.0.1: 6379>Lrange mykey 0 0
1) "e"
2. LPOP/LLEN:
Redis 127.0.0.1: 6379>Lpush mykey a B c d
(Integer) 4
Redis 127.0.0.1: 6379>Lpop mykey
"D"
Redis 127.0.0.1: 6379>Lpop mykey
"C"
# After the lpop command is executed twice, the two elements in the head of the linked list have been popped up. At this time, the number of elements in the linked list is 2.
Redis 127.0.0.1: 6379>Llen mykey
(Integer) 2
3. LREM/LSET/LINDEX/LTRIM:
# Prepare test data for the following example.
Redis 127.0.0.1: 6379>Lpush mykey a B c d a c
(Integer) 6
# From the left header to the right variable linked list, delete two elements whose values are equal to a and return the actual number of deleted elements.
Redis 127.0.0.1: 6379>Lrem mykey 2
(Integer) 2
# Shows all elements in the deleted linked list.
Redis 127.0.0.1: 6379>Lrange mykey 0-1
1) "c"
2) "d"
3) "c"
4) "B"
# Obtain the element value whose index value is 1 (the second element in the header.
Redis 127.0.0.1: 6379>Lindex mykey 1
"D"
# Set the element value of index value 1 (the second element in the header) to the new value e.
Redis 127.0.0.1: 6379>Lset mykey 1 e
OK
# Check whether the setting is successful.
Redis 127.0.0.1: 6379>Lindex mykey 1
"E"
# The index value 6 exceeds the number of elements in the linked list. This command returns nil.
Redis 127.0.0.1: 6379>Lindex mykey 6
(Nil)
# If the SET index value 6 exceeds the number of elements in the linked list, the setting fails. This command returns an error message.
Redis 127.0.0.1: 6379>Lset mykey 6 hh
(Error) ERR index out of range
# Only three elements with an index value ranging from 0 to 2 are retained. Note that both 0th and 2nd elements are retained.
Redis 127.0.0.1: 6379>Ltrim mykey 0 2
OK
# View the trim result.
Redis 127.0.0.1: 6379>Lrange mykey 0-1
1) "c"
2) "e"
3) "c"
4. LINSERT:
# Deleting this key facilitates subsequent tests.
Redis 127.0.0.1: 6379>Del mykey
(Integer) 1
# Prepare test data for the following example.
Redis 127.0.0.1: 6379>Lpush mykey a B c d e
(Integer) 5
# Insert a new element A1.
Redis 127.0.0.1: 6379>Linsert mykey before a a1
(Integer) 6
# Check whether the data is successfully inserted. The result shows that the data has been inserted. Note that the index value of lindex is 0-based.
Redis 127.0.0.1: 6379>Lindex mykey 0
"E"
# Insert the new element e2 to the end of e. The returned result shows that it has been successfully inserted.
Redis 127.0.0.1: 6379>Linsert mykey after e e2
(Integer) 7
# Check whether the insert operation is successful again.
Redis 127.0.0.1: 6379>Lindex mykey 1
"E2"
# Insert a new element before or after a nonexistent element. This command fails and-1 is returned.
Redis 127.0.0.1: 6379>Linsert mykey after k
(Integer)-1
# Insert a new element for a Key that does not exist. If this command fails, 0 is returned.
Redis 127.0.0.1: 6379>Linsert mykey1 after a a2
(Integer) 0
5. RPUSH/RPUSHX/RPOP/RPOPLPUSH:
# Delete the key to facilitate subsequent tests.
Redis 127.0.0.1: 6379>Del mykey
(Integer) 1
# Insert the values in the parameters at the end of the linked list. The insertion sequence is from left to right.
Redis 127.0.0.1: 6379>Rpush mykey a B c d
(Integer) 4
# Through lrange, we can know the insert sequence of rpush when inserting multiple values.
Redis 127.0.0.1: 6379>Lrange mykey 0-1
1) ""
2) "B"
3) "c"
4) "d"
# This key already exists and contains four elements. The rpushx command is executed successfully and Element e is inserted to the end of the linked list.
Redis 127.0.0.1: 6379>Rpushx mykey e
(Integer) 5
# The lindex command shows that the previous rpushx command was successfully executed, because the element with the index value of 4 is already a new element.
Redis 127.0.0.1: 6379>Lindex mykey 4
"E"
# Because the mykey2 key does not exist, the command does not insert data and the return value is 0.
Redis 127.0.0.1: 6379>Rpushx mykey2 e
(Integer) 0
# Before executing the rpoplpush command, first check the elements of the linked list in mykey and pay attention to their positional relationships.
Redis 127.0.0.1: 6379>Lrange mykey 0-1
1) ""
2) "B"
3) "c"
4) "d"
5) "e"
# Pop up the tail Element e of mykey and insert it to the header of mykey2 (atomically complete these two steps ).
Redis 127.0.0.1: 6379>Rpoplpush mykey mykey2
"E"
# Run the lrange command to view the result of mykey after the tail element is popped up.
Redis 127.0.0.1: 6379>Lrange mykey 0-1
1) ""
2) "B"
3) "c"
4) "d"
# Run the lrange command to view the result of mykey2 inserting an element.
Redis 127.0.0.1: 6379>Lrange mykey2 0-1
1) "e"
# Set source and destination as the same key and move the tail element of mykey to its header.
Redis 127.0.0.1: 6379>Rpoplpush mykey
"D"
# View the moving result.
Redis 127.0.0.1: 6379>Lrange mykey 0-1
1) "d"
2) ""
3) "B"
4) "c"
4. Tips on linked list structure:
For the Value of the linked list structure, Redis provides some practical skills in its official documentation, such as the RPOPLPUSH command, which is explained below.
Redis linked lists are often used in Message Queue services to exchange messages between multiple programs. Suppose an application is executing the LPUSH operation to add new elements to the linked list. We usually call such a program "Producer )", another application is executing the RPOP operation to retrieve elements from the linked list. We call this program "Consumer )". If, at this time, the consumer program crashes immediately after retrieving the message element, because the message has been removed and is not processed properly, we can think that the message has been lost, as a result, business data may be lost or the service status may be inconsistent. However, by using the RPOPLPUSH command, the consumer program extracts the message from the master message queue and then inserts it into the backup queue, after the consumer program completes the normal processing logic, the message is deleted from the backup queue. At the same time, we can also provide a daemon process. When a message in the backup queue expires, it can be re-stored in the primary message queue for other consumer programs to continue processing.