Подтвердить что ты не робот

Как обрабатывать сессию expire basing redis?

Я хочу реализовать базу данных session-store redis, я поместил данные сеанса в redis. Но я не знаю, как обрабатывать session-expire. Я могу закодировать все ключи redis (sessionid) и evaulate данные lastaccess и maxidle, поэтому мне нужно загрузить все ключи в клиенте, а возможно, 1000 м сеансовых ключей и может привести производительность ввода-вывода в пул.
Я хочу, чтобы redis управлял истечением срока действия, но при истечении срока действия ключа нет ответа или обратного вызова, поэтому тигра HttpSessionListener невозможно. любые советы?

4b9b3361

Ответ 1

Поэтому вам нужно, чтобы ваше приложение было уведомлено о завершении сеанса в Redis.

Хотя Redis не поддерживает эту функцию, существует ряд трюков, которые вы можете использовать для ее реализации.

Обновление: Начиная с версии 2.8.0, Redis поддерживает этот http://redis.io/topics/notifications

Во-первых, люди думают об этом: это все еще обсуждается, но оно может быть добавлено в будущую версию Redis. См. Следующие проблемы:

Теперь, вот некоторые решения, которые вы можете использовать с текущими версиями Redis.

Решение 1: исправление Redis

На самом деле, добавление простого уведомления, когда Redis выполняет истечение срока действия ключа, не так уж сложно. Его можно реализовать, добавив 10 строк в файл db.c исходного кода Redis. Вот пример:

https://gist.github.com/3258233

Этот короткий патч отправляет ключ в список #expired, если ключ истек и начинается с символа '@' (произвольный выбор). Его можно легко адаптировать к вашим потребностям.

Затем тривиально использовать команды EXPIRE или SETEX для установки времени истечения для ваших объектов сеанса и написать небольшой демон, который зацикливается на BRPOP для удаления из списка "#expired" и распространения уведомления в вашем приложении.

Важным моментом является понимание того, как работает механизм истечения срока действия в Redis. На самом деле есть два разных пути для истечения, оба одновременно действуют:

  • Ленивый (пассивный) механизм. Истечение срока действия может происходить каждый раз, когда к нему обращаются ключ.

  • Активный механизм. Внутренняя работа регулярно (случайным образом) отображает несколько ключей с установленным сроком действия, пытаясь найти те, которые истекают.

Обратите внимание, что вышеупомянутый патч отлично работает с обоими путями.

Следствием является то, что срок действия Redis не является точным. Если все ключи имеют истечение срока действия, но только один из них истекает, и к нему не обращаются, действие активного истечения может занять несколько минут, чтобы найти ключ и истек его. Если вам нужна точность в уведомлении, это не путь.

Решение 2: симуляция истечения с помощью zsets

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

Каждый раз, когда сеанс добавляется в Redis, вы можете запускать:

MULTI
SET <session id> <session content>
ZADD to_be_expired <current timestamp + session timeout> <session id>
EXEC

Сортированный набор to_be_expired - это просто эффективный способ доступа к первым ключам, срок действия которых истек. Демон может опросить on_be_expired, используя следующую серверную сторону Lua script:

local res = redis.call('ZRANGEBYSCORE',KEYS[1], 0, ARGV[1], 'LIMIT', 0, 10 )
if #res > 0 then
   redis.call( 'ZREMRANGEBYRANK', KEYS[1], 0, #res-1 )
   return res
else
   return false
end

Командой запуска script будет:

EVAL <script> 1 to_be_expired <current timestamp>

Демон получит не более 10 элементов. Для каждого из них он должен использовать команду DEL для удаления сеансов и уведомлять приложение. Если один элемент был фактически обработан (т.е. Возврат Lua script не является пустым), демон должен зацикливаться немедленно, иначе может быть введено состояние ожидания в 1 секунду.

Благодаря Lua script можно запускать несколько демонов опроса параллельно (script гарантирует, что данный сеанс будет обрабатываться только один раз, поскольку ключи удаляются из to_be_expired с помощью Lua script сам по себе).

Решение 3: используйте внешний распределенный таймер

Другое решение - полагаться на внешний распределенный таймер. облегченная система массового обслуживания - хорошая возможность для этого

Каждый раз, когда сеанс добавляется в систему, приложение отправляет идентификатор сеанса в очередь beanstalk с задержкой, соответствующей тайм-ауту сеанса. Демон слушает очередь. Когда он может деактивировать элемент, это означает, что сеанс истек. Он просто должен очистить сеанс в Redis и уведомить приложение.