Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Tracking online users using Redis

Tags:

redis

I want to track how many users are online, I use Redis to solve this problem as one or more number of application instances access this cache to display the statuses. On every new login the Redis is updated with the user-id, on the key "online_users", and on every logout the user is removed. Is this approach right, if not how to structure this for best performance, and somewhat big dataset?

"online_users" -> {
     user_s23,user_1f3,user_1mn,user_xd3
}

The user info is available in the cache as, is it right to include the status as another attribute?

user_s23 {
name, id, profile_pic, type, etc, status:active/inactive
}

Though this 2 approaches for tracking online users with Redis. Which one is faster? question's answer compares two approaches on this, the first link mentioned is unavailable, so I could not understand the other context.

like image 230
Vijay Veeraraghavan Avatar asked Feb 19 '14 11:02

Vijay Veeraraghavan


1 Answers

If you only want to know:

1- How many users are online

2- What users are online

3- Find if a given user is online

And you can ensure that you can track EVERY logout and ALL users call the logout request, then you can use a set and store the user id into it when user logs in and removes the userid when the user logs out (the same approach as you described).

Examples:

  • user_a logs in:

> sadd online_users user_a

(integer) 1

  • user_b logs in:

> sadd online_users user_b

(integer) 1

  • How many users are online?

> scard online_users

(integer) 2

  • Is user_a online?

> sismember online_users user_a

(integer) 1

  • user_a logs out:

> srem online_users user_a

(integer) 1

  • What users are online?

> smembers online_users

1) "user_b"

All these operations are O(1) except the smembers that is O(N), your only concern and limit is the memory used to store these data. A hint is to try to use smaller keys for your users, if you can't, Redis already compress them.

If you can't ensure that you will track the logouts, you can use the second approach of the question "2 approaches for tracking online users with Redis. Which one is faster?".

To use this approach you will need to track all events of a user (not only the login), and store the user id on different keys using a time stamp, like: online_users_2014-02-20_10-01 (online users at 10:01 of 02/20/2014).

To answer how many users are currently online, you can say, for example, that a user is considered online if he sent at least one event in the last 3 minutes. Then you calculate the union of the last 3 sets and use scard on the resulting set to find how many users are online.

This approach is much more expensive, because sunion is O(N). And is a good idea to add timeout (using the expire command) on your keys to keep help clean your memory.

Another approach based on the last one, is to add some logic on the client side, that send a PING event every minute in background for your backend, then you can track this event and you will have sure that the users in that set are online.

like image 104
fgasparini Avatar answered Nov 02 '22 15:11

fgasparini