ZREMRANGEBYSCORE is OP
ZREMRANGEBYSCORE is a Redis command to remove items from a sorted set by weight range. It is comically overpowered and should be abused before it gets nerfed in the next Redis balance patch.
You have data in Redis, but now you need to search it using some basic criteria. The general solution is to add a secondary index. So you create some sets, build the index, and gg wp no re.
But wait, the primary entities have a TTL. Now you can't guarantee your sets are referencing keys that have not expired. Manually checking each key and updating the set is far to expensive. How do you keep your sets in sync with the data they represent?
This is an exact scenario I encountered when trying to model Identity Server reference tokens. Access tokens are short lived by design, so the eviction churn would create some very large sets that are filled with dead references.
I needed the access tokens to be indexed by subject ID and client ID, as a user can revoke access tokens by these criteria. I created/updated a sorted set keyed on this data when an access token was created. The TTL of these sorted sets could have been set to the client's access token lifetime and slid as needed. However, the lifetime can technically be altered and I desired to have the data update in real time as access tokens are issued. So, a default TTL of the maximum allowed access token lifetime sufficed. How did I keep the sorted sets synchronized with the actual access token TTLs?
Sorted sets are Redis sets that also have a weight. Weight can be used in several useful operations. Remember the topical operation, ZREMRANGEBYSCORE
, which removes items by weight range. I assigned the weight of each entry in the sorted set to the Unix timestamp expiration of the relevant access token. Now whenever an access token is directly created or deleted I can simply evict entries in the associated sorted set with ZREMRANGEBYSCORE
.
Admittedly this is not flawless, as it is possible for an access token to slip by if a user does not request a new one for a client and then revokes all issued access tokens for that client. The sorted sets are maintained by user activity, so this would be unlikely. And if it did occur, the sorted set has been historically groomed by activity so it would not contain an unseemly number of de-referenced access tokens. It was acceptable to have a maybe few keys that do not map instead of nearly all of them.