Уведомления Redis 2.8: Получить значение вместо ключа (по истечении срока действия)

мы имеем следующий прецедент: каждый раз, когда истекает определенный ключ, нам нужно получить уведомление и сделать что-то, исходя из его значения. Но когда redis запускает событие expired, ключ уже был удален из db, когда мы попытаемся получить к нему доступ позже, что, конечно же, ожидается.

Теперь есть способ получить доступ к записи снова, после того как она истекло? Наверное, нет.

Итак, второй вариант: есть ли способ сообщить redis публиковать весь объект значения вместо того, чтобы просто отправлять эти события? Я предполагаю, что это может быть добавлено через Lua, но мне хотелось бы, если возможно, более простой вариант. Нам также нужно это поведение для других событий, нам в основном нужны все уведомления, чтобы опубликовать значение, а не ключ (мы могли бы сделать GET после получения события, но мы хотим обойти второй вызов, прежде всего, чтобы атомный процесс, поскольку значение могло быть изменено между публикацией события и выполнением GET для извлечения значения).

Надеюсь, это понятно. Может быть, мы не можем видеть очевидное, поэтому заранее спасибо!

Ответ 1

Функция, с которой связан Eli, позволяет вам слушать, когда истекает срок действия ключа. Однако он не дает вам значения ключа. Более того, на основе поданной проблемы github это выглядит не так, как вы можете ожидать, что эта функция будет построена в любое время в ближайшее время (https://github.com/antirez/redis/issues/1876), Решением, которое я использую, является создание специального ключа "теневого" срока действия, связанного с ключом, где у вас есть фактическое значение.

Итак, скажем, у вас есть ключ с именем testkey и он имеет целочисленное значение 100. Кроме того, ключ истекает через 10 секунд, после чего вы хотите получить значение ключа. (Возможно, вы увеличивали ключ в течение 10 секунд, когда он существовал).

Сначала вам нужно настроить прослушивание событий в ключевом пространстве. В частности, вы хотите слушать события expired. Вы можете сделать это из своей конфигурации или использовать команду config set в redis. (см. здесь для получения дополнительной информации: http://redis.io/topics/notifications)

CONFIG SET notify-keyspace-events Ex

Теперь вы можете подписаться на специальный канал keyevent, где вы будете уведомлены о том, что ключ истек.

SUBSCRIBE [email protected]__:expired

Формат канала для подписки - [email protected]<db>__:<eventName>. В нашем примере мы предполагаем, что мы работаем с базой данных по умолчанию 0 и хотим прослушать событие expired.

Когда истечет testkey, вы теперь получите сообщение в канале __keyevent__, где это сообщение - это имя ключа, который истек. Конечно, в этот момент ключ ушел, поэтому мы больше не можем получить доступ к значению! Решение состоит в использовании специального ключа срока действия.

Когда вы создаете свой testkey, также создайте специальный истекающий "теневой" ключ (срок действия testkey не истекает). Например:

SET testkey 100
SET shadowkey:testkey "" EX 10

Теперь в канале [email protected]__:expired вы получите сообщение о том, что ключ shadowkey:testkey истек. Возьмите значение сообщения (которое является именем ключа), разделите двоеточие (или какой-либо разделитель, который вы решили использовать), а затем вручную получите значение ключа и удалите его.

// set your key value
SET testkey 100 
//set your "shadow" key, note the value here is irrelevant
SET shadowkey:testkey "" EX 10 
// Get an expiration message in the channel [email protected]__:expired
// Split the key on ":", take the second part to get your original key
// Then get the value and do whatever with it
GET testkey
// Then delete the key
DEL testkey

Обратите внимание, что значение shadowkey не используется, поэтому вы хотите использовать наименьшее возможное значение, которое в соответствии с этим ответом (Redis сохраняет ключ без значения) является пустой строкой "". Это немного больше работы по настройке, но вышеуказанная система делает именно то, что вам нужно. Накладные расходы - это несколько дополнительных команд для фактического извлечения и удаления ключа плюс стоимость хранения пустого ключа.

Ответ 2

Если вы на 2.8, вы можете попробовать эту новую функцию (также упоминается в эта страница). Это определенно неустойчиво и не кажется хорошо проверенным, но если вы все равно на 2.8...

Короткое введение страницы проблемы:

Интересная функция в базах данных с моделью данных с ключом (Redis не идеально подходит для этого определения, поскольку значения являются сложными данными структура, но внешний слой Redis определенно является ключевым значением бизнес) - это способность каким-то образом подписаться на поток события, нацеленные на заданный ключ.

Например, мне может быть интересно узнать, когда ключ foo удален или изменено каким-либо образом или для получения имен всех ключей с помощью expire set (используя команду EXPIRE), которую Redis выказывает из dataset, потому что их время жить упало до нуля.

Эта функция неоднократно запрашивалась у пользователя Redis, однако до сих пор мы не достигли точки, в которой предлагаемый API (включая предложения, сделанные мною), похоже, хорошо вписывались в дизайн Редиса. Этот запрос функции попытается описать новый дизайн, который чрезвычайно прост в использовании, реализовать и хорошо вписывается в Redis история.