Мне нужно истечь срок действия всех ключей в хэше Redis, которые старше 1 месяца.
108
Это невозможно из соображений простоты Redis .
Куот Антирез, создатель Redis:
Привет, это невозможно, либо используйте другой ключ верхнего уровня для этого конкретного поля, либо сохраните вместе с поданным другим полем с истечением времени, выберите оба и дайте приложению понять, действительно ли он все еще действителен или нет, на основе Текущее время.
Redis не поддерживает использование
TTL
хешей, кроме верхнего ключа, что приведет к истечению срока действия всего хэша. Если вы используете сегментированный кластер, вы можете использовать другой подход. Этот подход может быть полезен не во всех сценариях, а характеристики производительности могут отличаться от ожидаемых. Еще стоит упомянуть:При наличии хеша структура в основном выглядит так:
Поскольку мы хотим добавить
TTL
дочерние ключи, мы можем переместить их в верхние ключи. Главное, что ключ теперь должен быть комбинациейhash_top_key
дочернего ключа:Мы
{}
намеренно используем обозначения. Это позволяет всем этим ключам попасть в одно и то жеhash slot
. Вы можете прочитать об этом здесь: https://redis.io/topics/cluster-tutorialТеперь, если мы хотим проделать ту же операцию с хешами, мы могли бы сделать:
Вот интересный
HGETALL
. Сначала мы получаемhash slot
для всех наших дочерних ключей. Затем мы получаем ключи для этого конкретногоhash slot
и, наконец, получаем значения. Здесь нам нужно быть осторожными, поскольку для этого может быть больше, чемn
ключей,hash slot
а также могут быть ключи, которые нам не интересны, но у них такие жеhash slot
. Мы могли бы написатьLua
сценарий для выполнения этих действий на сервере, выполнив командуEVAL
илиEVALSHA
. Опять же, вам необходимо принять во внимание производительность этого подхода для вашего конкретного сценария.Еще несколько ссылок:
источник
Существует Java-фреймворк Redisson, который реализует хэш-
Map
объект с поддержкой TTL входа. Он используетhmap
иzset
объекты Redis под капотом. Пример использования:Этот подход весьма полезен.
источник
Это возможно в KeyDB, который является форком Redis. Поскольку это вилка, она полностью совместима с Redis и работает как капля замены.
Просто используйте команду EXPIREMEMBER. Он работает с наборами, хешами и отсортированными наборами.
Вы также можете использовать TTL и PTTL, чтобы увидеть срок действия
Дополнительная документация доступна здесь: https://docs.keydb.dev/docs/commands/#expiremember
источник
Что касается реализации NodeJS, я добавил настраиваемое
expiryTime
поле в объект, который сохраняю в HASH. Затем по прошествии определенного периода времени я очищаю просроченные записи HASH, используя следующий код:источник
Array.filter
для создания массиваkeys
для удаления из хэша, а затем передать егоclient.hdel(HASH_NAME, ...keys)
за один вызов.const keys = Object.keys(reply).filter(key => reply[key] && JSON.parse(reply[key]).expiryTime < Date.now()); client.hdel(HASH_NAME, ...keys);
Ты можешь. Вот пример.
Используйте команду EXPIRE или EXPIREAT .
Если вы хотите, чтобы срок действия определенных ключей в хэше истек более 1 месяца. Это невозможно. Команда Redis expire предназначена для всех ключей в хэше. Если вы установите ежедневный хэш-ключ, вы можете установить время жизни ключей.
источник
Для этого вы можете хранить ключи / значения в Redis по-другому, просто добавляя префикс или пространство имен к вашим ключам при их сохранении, например, "hset_"
Получите ключ / значение,
GET hset_key
равноеHGET hset key
Добавьте ключ / значение,
SET hset_key value
равноеHSET hset key
Получить все ключи
KEYS hset_*
равноHGETALL hset
Получить все валы нужно за 2 операции, сначала получить все ключи,
KEYS hset_*
затем получить значение для каждого ключаДобавьте ключ / значение с TTL или истечение срока действия, о котором идет речь:
Примечание :
KEYS
будет искать соответствующий ключ во всей базе данных, что может повлиять на производительность, особенно если у вас большая база данных.Примечание:
KEYS
будет искать соответствующий ключ во всей базе данных, что может повлиять на производительность, особенно если у вас большая база данных. whileSCAN 0 MATCH hset_*
может быть лучше, если он не блокирует сервер, но все же производительность является проблемой в случае большой базы данных.Вы можете создать новую базу данных для отдельного хранения этих ключей, срок действия которых истекает, особенно если это небольшой набор ключей.
источник
hashset
... получить O (1) установить O (1) получить все O (n)O(n)
для количества вещей в наборе,KEYS
для количества вещей в БД.scan 0 match namespace:*
может быть лучше, если он не блокирует серверУ нас была та же проблема, о которой здесь говорилось.
У нас есть хэш Redis, ключ к хеш-записям (парам имя / значение), и нам нужно было хранить индивидуальное время истечения срока для каждой хеш-записи.
Мы реализовали это, добавив n байтов префиксных данных, содержащих закодированную информацию об истечении срока действия, когда мы записываем значения записи хэша, мы также устанавливаем срок действия ключа на момент, содержащийся в записываемом значении.
Затем, при чтении, мы декодируем префикс и проверяем срок его действия. Это дополнительные накладные расходы, однако чтение по-прежнему O (n), и весь ключ истечет, когда истечет последняя запись хэша.
источник
Вы можете использовать уведомления Redis Keyspace, используя
psubscribe
и"__keyevent@<DB-INDEX>__:expired"
.При этом каждый раз, когда истечет срок действия ключа, вы будете получать сообщение, опубликованное в вашем соединении Redis.
Что касается вашего вопроса, в основном вы создаете временный «нормальный» ключ, используя
set
время истечения срока в с / мс. Он должен соответствовать имени ключа, который вы хотите удалить в своем наборе.Поскольку ваш временный ключ будет опубликован в вашем соединении Redis с сохранением,
"__keyevent@0__:expired"
когда истечет срок его действия, вы можете легко удалить свой ключ из исходного набора, так как в сообщении будет указано имя ключа.Простой пример на практике на этой странице: https://medium.com/@micah1powell/using-redis-keyspace-notifications-for-a-reminder-service-with-node-c05047befec3
документ: https://redis.io/topics/notifications (ищите флаг xE)
источник
Вы можете использовать Sorted Set в redis, чтобы получить контейнер TTL с отметкой времени в качестве оценки. Например, всякий раз, когда вы вставляете строку события в набор, вы можете установить его счет на время события. Таким образом, вы можете получить данные любого временного окна, позвонив
zrangebyscore "your set name" min-time max-time
Более того, мы можем истечь, используя
zremrangebyscore "your set name" min-time max-time
для удаления старых событий.Единственным недостатком здесь является то, что вам придется выполнять служебные обязанности стороннего процесса, чтобы поддерживать размер набора.
источник
Вы можете легко истечь хэши Redis, например, используя python
Это истекут все дочерние ключи в хэш hashed_user через 10 секунд
то же самое из redis-cli,
через 10 секунд
источник
hset
ребенок не полныйhset
.