I find it very easy to count number of active connections using
redis_sip = redis.Redis(host="localhost", port=6379, db=0)
redis_sip.setbit(skey, 1, 1)
redis_sip.setbit(skey, 2, 1)
redis_sip.setbit(skey, 3, 0)
redis_sip.setbit(skey, 4, 1)
print(redis_sip.bitcount(skey)) # shows me 3 connections
But for this to work I need to be able to set a TTL for each individual bit.
i.e. when a remote agent makes a connection, I can set the bit to 1. If bitwise expiry is supported, then the bit will be flipped after a length of inactivity.
Is it doable at all in Redis? If not, what is an alterantive?
2
Answers
NO, you cannot expire a bit.
Instead, you can only expire a key. So in order to achieve your goal, when a connection established, you can set a key with a timeout. When you want to get the total number of connections, use the
DBSIZE
command.Also, you should be careful with
SETBIT
command. If an agent with a large id, say, 100000000, establishes a connection, when setting the corresponding bit, Redis needs to allocate lots of memory, and might block for a while. See the doc for detail.As noted, Bitmaps do not support bit-level expiry. In fact, none of the core Redis data structures provide nested-element expiry.
An easy alternative would be to use Sorted Sets. For each new connection,
ZADD
it as a member with a score that is the current timestamp (epoch). Then, in order to obtain a count, do aZREMRANGEBYSCORE
from ‘-inf’ to the current time minus your “TTL” – this will “trim” the zset to include only non-expired connections. Lastly, you can callZCARD
to obtain the cardinality/count of members.