preface

This article is from the blog, to view the latest article, please click view blog, welcome everyone to pay attention to and discuss

I. Principle of rename

When the rename oldKey newKey command is used, the following two operations are performed

1. Implicitly delete newKey

Since the rename operation is not renameNX, it is mandatory to change the old Key name to the new Key name. So if the new Key name refers to data, Redis must delete the data first!

Note: The Value corresponding to key is abstracted into memory

(1) the source code

In Redis, both rename and renameNX commands execute a generic renameGenericCommand function, except that the second NX parameter is passed differently. The client parameter, as its name indicates, is used to retrieve the parameters carried by the command

  • C – > argv [1] oldKey said
  • C – > argv [2] the newKey said

So the core is the renameGenericCommand function

If (lookupKeyWrite(c->db,c->argv[2])! = NULL), where lookupKeyWrite returns the memory pointer to which the Key points. If it is not NULL, the data store already exists, so the newKey deletion logic is followed

(2) Time complexity

The time complexity is O(M), where M is the number of members

(3) test

Write a Hash bigkey with 500W members. As shown in the following figure, the memory is increased by about 400MB. Deleting the bigkey takes about 3 seconds

We then execute the rename operation and the result is as follows

So the rename operation implicitly deletes the newKey, and the deletion takes O(M).

2. Modify pointer pointing

Redis has the following two methods to rename. The first method is to copy data, and the second method is to modify the pointer. If the value copy mode is adopted, the memory peak of Redis will increase, and the memory copy time will also increase the time consuming. The most important value copy is not needed in the Redis scenario, so Redis uses the second method to modify the pointer

Note: The Value corresponding to key is abstracted into memory

(1) the source code

In the following source code, after getting the pointer to the memory object (value object) oldKey points to, mark it as O, and then do the following operations

  • Increment the o reference count by 1, so that the reference count of O is 2
  • Adding the new key-value relation (newKey => O) to the current DB is equivalent to redirecting newKey to O
  • Deleting the oldKey (oldKey => o) relation is equivalent to deleting the reference to oldKey

Since o has a reference count of 2, o still has a reference count of 1 after oldKey is removed and GC is not triggered, so the memory occupied by object O is still valid, but instead is pointed to by newKey

(2) Time complexity

O(1)

3, summarize

A rename operation that takes O(1) is inaccurate and should be O(M)+O(1).

  • O(M) is the newKey deletion time, and there is a linear relationship between the member and the deletion time
  • O(1) for newKey points to the time of new memory, which is constant and negligible

Second, rename the complete process

  1. Find newKey: Finds the value object to which newKey points
  2. Delete Memory A: Deletes the memory pointed to by the value object
  3. Find oldKey: Finds the value object to which oldKey points
  4. IncrRefCount: The reference count for the value object to which oldKey points +1
  5. Add relation: Adds (newKey => O) the new key-value pair information to the database, making newKey point to a new value object
  6. Delete Relation: Delete (oldKey => O) the old key-value pair information so that oldKey no longer refers to the previous value object

Note: The Value corresponding to key is abstracted into memory

3. Some questions about Rename

1. Is rename atomic

If the second step fails, the first operation is not rolled back, so it is not atomic

2. Is the delete operation in rename synchronous

Whether it is synchronous or asynchronous, as you can see from the code, depends entirely on the DEL mechanism configured, that is, by the lazyfree-lazy-server-del configuration.

3. How to solve the time-consuming problem of RENAME

In the previous test, it is found that the rename operation card takes 3 seconds. Run the config get * command, and it is found that the correct deletion mode is synchronous deletion

So there are two solutions, either reduce the number of member members of the Key, or set lazyfree-lazy-server-del to yes

Fourth, concluding remarks

This article has ended, the ability is limited, the article error place please kindly point out, thank you for reading