Redis
 sql >> база данни >  >> NoSQL >> Redis

как да се справя с изтичането на сесията, базирайки се на redis?

Така че трябва вашето приложение да бъде уведомено, когато сесията изтече в Redis.

Въпреки че Redis не поддържа тази функция, има редица трикове, които можете да използвате, за да я приложите.

Актуализация:От версия 2.8.0 Redis поддържа това http://redis.io/topics/notifications

Първо, хората мислят за това:това все още се обсъжда, но може да бъде добавено към бъдеща версия на Redis. Вижте следните проблеми:

  • https://github.com/antirez/redis/issues/83
  • https://github.com/antirez/redis/issues/594

Ето някои решения, които можете да използвате с текущите версии на 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 е просто ефективен начин за достъп до първите ключове, които трябва да изтекат. Демон може да анкетира to_be_expired, използвайки следния Lua скрипт от страна на сървъра:

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

Командата за стартиране на скрипта ще бъде:

EVAL <script> 1 to_be_expired <current timestamp>

Демонът ще получи най-много 10 артикула. За всеки от тях той трябва да използва командата DEL, за да премахне сесиите и да уведоми приложението. Ако един елемент действително е бил обработен (т.е. връщането на Lua скрипта не е празно), демонът трябва да завърже незабавно, в противен случай може да се въведе състояние на изчакване от 1 секунда.

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

Решение 3:използвайте външен разпределен таймер

Друго решение е да разчитате на външен разпределен таймер. Олекотената система за опашка на бобови стъбла е добра възможност за това

Всеки път, когато се добави сесия в системата, приложението публикува идентификатора на сесията в опашка на beanstalk със закъснение, съответстващо на времето за изчакване на сесията. Демон слуша опашката. Когато може да извади елемент от опашката, това означава, че сесията е изтекла. Просто трябва да почисти сесията в Redis и да уведоми приложението.




  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Heroku:Фонови задачи в Python с RQ

  2. Конфигуриране на redis за последователно премахване на по-стари данни първо

  3. вложеното изключение е redis.clients.jedis.exceptions.JedisConnectionException:Не можа да се получи ресурс от пула

  4. Задачата за целина винаги ИЗЧАКВА

  5. ImportError:Няма модул с име redis