Почему redis RENAME выполняет неявное DEL, а не UNLINK? - PullRequest
0 голосов
/ 09 июля 2020

Как сказано в документах RENAME :

Переименовывает ключ в newkey. Если ключ не существует, он возвращает ошибку. Если новый ключ уже существует, он перезаписывается, когда это происходит RENAME выполняет неявную операцию DEL , поэтому, если удаленный ключ содержит очень большое значение, это может вызвать высокую задержку , даже если RENAME само обычно операция с постоянным временем.

Как мы знаем, DEL блокируется, а UNLINK не блокирует.

Итак, у меня есть два вопроса:

  • Если удаленный ключ содержит очень большое значение, кажется, что выполнение неявного UNLINK было бы лучше. Почему redis решает использовать DEL?

  • Если я вручную выполню UNLINK, а затем RENAME с транзакцией, можно будет избежать большой задержки?

1 Ответ

1 голос
/ 09 июля 2020

«Неявная операция DEL» - это не то же самое, что команда DEL, вызываемая пользователем. Вы можете настроить его на использование asyn c или syn c delete. Причина этого в том, чтобы, вероятно, дать пользователю больше контроля.

В файле конфигурации redis со стороны LAZY FREEING написано:

DEL , UNLINK и ASYN C опции FLUSHALL и FLUSHDB управляются пользователем. Это зависит от дизайна приложения, чтобы понять, когда лучше использовать одно или другое. Однако серверу Redis иногда приходится удалять ключи или грипп sh всю базу данных в качестве побочного эффекта других операций. ** В частности, Redis удаляет объекты независимо от вызова пользователя в следующем сценарии ios:

.... Например, команда RENAME может удалить содержимое старого ключа, если оно заменено> другим. ....

Во всех вышеперечисленных случаях по умолчанию объекты удаляются блокирующим образом, как если бы был вызван DEL. Однако вы можете настроить каждый случай отдельно , чтобы вместо этого освободить память неблокирующим способом , как если бы был вызван UNLINK, используя следующие директивы конфигурации.

Тогда есть конфигурация

lazyfree-lazy-server-del no

Просто переключите его на YES, тогда он будет вести себя как UNLINK

I проверил исходный код,

Для Redis версии 5.0 эта функция вызывается при вызове команды RENAME.

void renameGenericCommand(client *c, int nx) {
// some code....
// When source and dest key is the same, no operation is performed,
// if the key exists, however we still return an error on unexisting key. 
if (sdscmp(c->argv[1]->ptr,c->argv[2]->ptr) == 0) samekey = 1;

// some code ...

if (samekey) {
    addReply(c,nx ? shared.czero : shared.ok);
    return;
}
       ...
    /* Overwrite: delete the old key before creating the new one
     * with the same name. */
    dbDelete(c->db,c->argv[2]);
}

Это функция dbDelete , которую она вызвала

int dbDelete(redisDb *db, robj *key) {
return server.lazyfree_lazy_server_del ? dbAsyncDelete(db,key) :
                                         dbSyncDelete(db,key);

}

Как видите, это относится к конфигурации lazyfree-lazy-server-del

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...