Виноград
Синтаксис команд
Значение команды: установите время жизни для данного ключа. Когда срок действия ключа истечет (время действия равно 0), он будет автоматически удален. Формат команды:
EXPIRE key seconds
Командуйте реальным боем:
redis> EXPIRE cache_ Page 30000 update expiration time (integer) 1
Возвращаемое значение:
Установка успешно возвращена 1. Если ключ не существует или не может быть установлен на срок службы ключа (например, вы пытаетесь обновить срок службы ключа в redis в версии 2.1.3), возвращается 0.
Анализ исходного кода:
Функция истечения срока действия-expircommand:
/* EXPIRE key seconds */
void expireCommand(client *c) {
//Call general handler
expireGenericCommand(c,mstime(),UNIT_SECONDS);
}
/*This is a common command implementation for expire, pexpire, expireat, and pexpireat. Because the second parameter of commad can be relative,
It can also be absolute, so the "base time" parameter is used to indicate what the base time is (for the at variable of the command, or the current time of relative expiration).
The unit is unit second or unit millisecond, only used for argv [2] parameter. The base time is always specified in milliseconds. * /
void expireGenericCommand(client *c, long long basetime, int unit) {
robj *key = c->argv[1], *param = c->argv[2];
Long long when; / * when is set to milliseconds*/
/*Take out the integer value in param or try to convert the data in param to integer value as much as possible,
If ok is returned successfully, err is returned*/
if (getLongLongFromObjectOrReply(c, param, &when, NULL) != C_OK)
return;
/*If the incoming expiration time is in seconds, convert it to milliseconds*/
if (unit == UNIT_SECONDS) when *= 1000;
when += basetime;
/*Check whether the key exists and return information to the client*/
if (lookupKeyWrite(c->db,key) == NULL) {
addReply(c,shared.czero);
return;
}
/*
*When loading AOF data, or when the server is a satellite node,
*Even if the TTL of express is negative, or the timestamp provided by express has expired,
*The server will not actively delete the key, but wait for the master node to send an explicit del command.
*/
if (when <= mstime() && !server.loading && !server.masterhost) {
//Conditions for entering this function: when the time provided has expired, no data has been loaded and the server is the primary node (note that the masterhost = = null of the primary server)
robj *aux;
/*Delete this key. Here you can see the resolution of del command. In the resolution of del command, there are policy decisions to analyze the synchronous and asynchronous deletion of redis, which will not be discussed here*/
int deleted = server.lazyfree_lazy_expire ? dbAsyncDelete(c->db,key) :
dbSyncDelete(c->db,key);
serverAssertWithInfo(c,key,deleted);
server.dirty++;
/* Replicate/AOF this as an explicit DEL or UNLINK. */
/*Propagate del or unlink commands to AOF or from the server*/
aux = server.lazyfree_lazy_expire ? shared.unlink : shared.del;
/*Modify the parameter array of the client*/
rewriteClientCommandVector(c,2,aux,key);
/*Send key change notification*/
signalModifiedKey(c->db,key);
notifyKeyspaceEvent(NOTIFY_GENERIC,"del",key,c->db->id);
addReply(c, shared.cone);
return;
} else {
//Set key expiration time
//If the server is a satellite node, or the server is loading, it can be inferred according to the conditions in the previous if, at least when the provided time expires as a satellite node will be set
//It is speculated that in redis, the secondary node does not actively delete, unless the primary node synchronizes the Del command
//So when might have expired
setExpire(c,c->db,key,when);
addReply(c,shared.cone);
signalModifiedKey(c->db,key);
notifyKeyspaceEvent(NOTIFY_GENERIC,"expire",key,c->db->id);
server.dirty++;
return;
}
}
//Set expire
void setExpire(client *c, redisDb *db, robj *key, long long when) {
dictEntry *kde, *de;
/* Reuse the sds from the main dict in the expire dict */
/*First, search from dict, which is the process of searching from Dict Of DB according to key. First, we will judge whether there is a security iterator. If not, we will rehash to prevent ha
*Hope is chaos. Then hash to get the index value. Through the index, we can traverse the list of dict to get the value. There will be the same hash value on dict, here
*Redis uses the while loop to compare, knowing that the same key returns this item.
*/
kde = dictFind(db->dict,key->ptr);
serverAssertWithInfo(NULL,key,kde != NULL);
/*The workaround of dictaddraw() is just a procedure returned if there is a key. If there is a key, it will return null and return the current item. Otherwise, it will hash the key
*Index is added to dict and returns dict.
*/
de = dictAddOrFind(db->expires,dictGetKey(kde));
/*Set key expiration time
*Here is to directly use integer value to save expiration time, not int encoded string object
*/
dictSetSignedIntegerVal(de,when);
int writable_slave = server.masterhost && server.repl_slave_ro == 0;
if (c && writable_slave && !(c->flags & CLIENT_MASTER))
rememberSlaveKeyWithExpire(db,key);
}Давайте возьмем юридический пример GDB, чтобы увидеть его процесс:
- Во-первых, давайте войдем в сервер и клиент GDB
- Мы видим, что действие после ввода getlongfromobjectorreply состоит в том, чтобы удалить целочисленное значение в параметре или попытаться преобразовать данные в параметре в целочисленное значение как можно больше. Когда печатается, и значение равно 50000, как мы установили
- Судите сами, секунда ли это. Если это так, то оно будет преобразовано в миллисекунду. Затем добавьте базовое время. В результате время UNIX преобразуется в 2019-09-23 05:30:15 (примерно через 13 часов), что соответствует ожиданиям. Следующий шаг
- Следующий шаг-выяснить, есть ли ключ. Если он есть, перейдите к следующему шагу
- Поскольку мы обычно устанавливаем срок действия, мы должны использовать оператор else для установки. Настройка заключается в том, чтобы найти свой ключ в базе данных redis, а затем обновить время истечения срока действия. См. Анализ кода выше для конкретной реализации:
- Следующий шаг-подать сигнал клиенту.
- Мы продолжаем выполнять команду C и получаем от клиента сообщение об успешном выполнении
сравнивать
Существует три вида команд redis: Express, expiration, pexpireat Функция express at аналогична express, которая используется для установки времени жизни ключа. Разница в том, что параметр времени, принятый командой expire, является меткой времени UNIX. Разница между expire, expire и express и express заключается в истечении срока действия, срок действия-в миллисекундах, а последний-в секундах.
Деловое использование
Здесь я просто перечисляю несколько пунктов для вашей справки:
- Информация о предложении с ограниченным сроком действия
- Кэш данных веб-сайта (для некоторых данных, которые необходимо регулярно обновлять, например: табло)
- Проверочный код мобильного телефона
- Ограничьте частоту посещений веб-сайта (например, максимум 10 посещений в минуту).