I need a data structure similar to a Python set in redis, with the additional capability of individual elements automatically expiring (getting popped) from the set 30 days after insertion. Basically, these are the abstract behaviours I want out of the class.
from abc import abstractmethod, ABC
from typing import Iterable
class RedisSet(ABC):
"""Implement a set of strings with a remote redis host."""
@abstractmethod
def __init__(self, url:str):
"""
Initialise the class at the remote redis url.
The set of strings should be empty initially.
"""
raise NotImplementedError
@abstractmethod
def add(self, new_elements:Iterable[str])->None:
"""Insert all the elements into the set."""
raise NotImplementedError
@abstractmethod
def __contains__(self, elem:str)->bool:
"""Check membership."""
raise NotImplementedError
So what would be the cleanest way of achieving it? I do not need the entire class implemented, but asking what would be the correct data types and APIs to use in redis, as I am not thoroughly familiar with full capabilities of redis.
I noted redis has a set datatype, but seems (happy to be corrected if I am wrong) it does not support any time to live (TTL). Au contraire, the dictionary supports TTL, but I have to use a placeholder value
for each key (unnecessary overhead) and I am not sure whether the membership check will be constant time.
N. B.
- I do not foresee any need to iterate through the elements, so optimising with respect to that operation is superfluous. All I need is membership check.
- I intend to use
aioredis
as python client. It should support the necessary redis operations.
Any idea of the correct redis data types whose documentations I should look up will be greatly appreciated.
To achieve a similar functionality you want in
Redis
you should consider that there is a limitation withRedis
and the final solution may seem complex.What is the limitation?
As you mentioned correctly,
Redis
doesn't provide aTTL
feature with HASH, SETS, or any other data types. Just support the simple Key/Value.What is the solution?
You can use SortedSet. This data type gets a score for each element you add to it which in this case will be the expiration time. You need to maintain the sorted set by the code to remove expired elements from it. You can implement this part with a scheduler.
Add new Elements
(integer) ${number}
-${number}
determine the number of element you added, if you get 0 or less than your input elements means you've just updated the score of the element.Check Existance
Now you can check the existance of a key by this command, Note that you need to verify that the elememnt is not expired, so in you code need to check the time with the score.
(nil)
means the element does not existRemoving outdated elements
This is run by the your schaduler to remove element that are expired from the
sorted set
Unfortunately, I'm not a Python developer and can't help you with the code. But I think this code help you to get insight: