Redis expiration is a very common operation, after all, Redis is not designed for persistent storage.

The problem

Redis’s built-in expiration mechanism can only expire on keys, not specific values, but some values may need to expire in certain scenarios. Imagine a scenario where there is an article identified by a unique ID. There is a requirement to count the number of articles read within 15 minutes of each article, once a minute, and then see how much the article is read. So the data form is roughly as follows:

[1.5.6.10.16. ]Copy the code

However, I only need the data within 15 minutes, otherwise the memory may be insufficient, at this time using the key expiration way can not meet the requirements, so I can use some features of Redis to complete this requirement.

The solution

The ordered collection of Redis can store a series of ordered values, for which score can be specified, and then sorted according to score:

ZAAD key score value
Copy the code

Then, the corresponding value of score within a certain range can be obtained through ZRANGEBYSCORE.

ZRANGEBYSCORE key score1 score2
Copy the code

You can use this feature above to fulfill requirements.

The number of articles read can be Redis by adding the following format, with the id of the article as key, the current timestamp as score, and the number of articles read as value. Something like this:

#Article ID Timestamp read number
ZADD id    1577591750 54
Copy the code

Then we get the count of the number of readings in 15 minutes, assuming the current timestamp is now:

ZRANGEBYSCORE id now - 15 * 60 now
Copy the code

This will do the trick, but it’s not perfect because over time, the ordered list will get longer and longer, and eventually the memory will explode. So every time we get a value that is less than 15 minutes old, we have to delete the value that is more than 15 minutes old, so that it has the same effect as expiration:

ZRANGEBYSCORE id 0 now - 15 * 60
Copy the code

Now it looks perfect, fulfilling the requirements and saving memory. However, there is a slight problem. Assuming the article is no longer accessed, the value will stay in memory forever (assuming no downtime). To be on the safe side, we can set this key to expire as well:

#After 24 hours, the entire key expires and the memory is reclaimed
EXPIRE key 24* 60 * 60
Copy the code

Now it’s perfect. It meets the requirements, but it also saves memory. Not to bore you, but this is a bit of a problem from a functional point of view, because the values stored in an ordered collection can only be unique, which is a bit of a problem if both counts have the same number of reads. This is also easy to solve, just design each value into the following form:

{
    value: numbers,
    timestamp: 1577591750
}
Copy the code

This way, each value is unique, which is really perfect. The schematic diagram is as follows:

Only the values in the yellow box are valid, and this box represents 15 minutes of validity. The value outside the box represents the expired value.

The original

Follow the wechat official account and chat about other things