NoSQL. Redis. Kоличество online-человек

Вопрос который мучает уже пару дней.

Есть приложение, которое использует mysql для хранения информации про пользователей и nosql/redis для обеспечения быстрой записи/чтения информации.

Этих процедур (чтения/запись) проходит очень много, по этому выбран редис.

часть задачи полностью портируется на redis. но есть вопрос на который не могу пока найти решение.

Приложение должно показывать количество людей «онлайн».

Если на sql можно при запросе обновлять поле online текущим timestamp и потом сделать where online>timestamp-15m и все покажет

то как быть в key-value хранилище пока не могу никак понять.

был вариант создавать ключ, который менялся бы раз в 15 минут. Например:
online_20110602_13_0
online_20110602_13_1
online_20110602_13_2
online_20110602_13_3
online_20110602_14_0
online_20110602_14_1


и писать туда +1 если запрос был в эти 15 минут.

Но такой вариант не приемлем, так как при переходе с 14 на 15 минуту счетчик будет показывать 0.

В общем вопрос такой. Как вывести и сохранять «онлайн» людей.

(ПС: Есть вариант писать текущие секунды, а потом в цикле по убыванию считывать последние 900 (15минут) и считать их, но это мне кажется через задницу решение)
  • Вопрос задан
  • 3688 просмотров
Решения вопроса 1
denver
@denver
Ок, вариант получше :) хранить айдишники юзеров в поминутных ключах online_20110602_13_00, ..., online_20110602_13_59, устанавливая каждому TTL 15 минут, добывать с помощью sunion из последних 15 ключей. Если точность не особо важна, то можно не поминутно, а попятиминутно хранить.
Ответ написан
Пригласить эксперта
Ответы на вопрос 3
denver
@denver
По вашему варианту — если ж писать +1 по каждому запросу, то будет не кол-во онлайн пользователей, а хитов. Выходит, чтобы не было дубликатов по-любому нужно хранить ID пользователей.

Я задачу решал так: записываю в редис (sadd) айдишник и ставлю/пролонгирую «отложенную» задачу (memcacheq) удалить его (srem) через 15 минут.
Ответ написан
@Suor
Можно так:
при хите — ZADD guys_online <unix_timestamp> <user_id>
получить число онлайн ребят — ZCOUNT guys_online <unix_timestamp-15*60> +inf
время от времени чистить старые записи
— ZREMRANGEBYSCORE guys_online -inf (<unix_timestamp-15*60>
Ответ написан
donnerjack13589
@donnerjack13589
io.js core developer
Можно использовать zadd и zremrangebyscore, например, как вот тут: github.com/donnerjack13589/redis.tracker/blob/master/lib/tracker/announcer.js#L44-53
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы