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