Redis

Redis ZSET

“Do you want to implement a real-time leaderboard for your next online game with Redis? Redis provides an out-of-the-box solution for this with ZSETs, which is a short name for Redis Sorted sets and is a tool that every Redis user must be familiar with.

Redis ZSET is an ordered collection of unique members where each member is associated with a score value. To highlight, the ZSETs are ordered by their score value by default which makes them quite different from the regular SET type. In addition, more than one member can hold the same score value, and the members will be ordered lexicographically in that case. The Redis ZSETs are a better choice for priority queues, secondary indexing, low-latency leaderboards, and rate limiters. Because ZSETs provide real-time demands such as responsiveness and in-memory access with low latency.

Furthermore, each member is assigned a rank value based on their position in the ZSET that is more like a 0-based index in a Java array.”

A Quick Look at Basic ZSET Commands

Several basic commands are available to add, fetch, and remove members from a ZSET(Sorted set) stored at a given ZSET key. Let’s have a quick look at three main commands: ZADD, ZRANGE, ZRANK, and ZREM.

A Real-time Pokemon Game Leaderboard example will be demonstrated here.

ZADD Command

Upon user registration, we need to add each user to our ZSET named Pokemon:Leaderboard. So, the ZADD command is the ideal candidate to use as follows. Assume we got five players registered initially. So, the scores will be assigned to 0.

ZADD Pokemon:Leaderboard 0 john

The return value is 1, which means one member has been added to the ZSET stored at key Pokemon:Leaderboard. If the member is already available in the given ZSET, only the score value will be updated.

We are all good to proceed. So, let’s go ahead and add the remaining four players to the ZSET: Pokemon:Leaderboard.

ZADD Pokemon:Leaderboard 0 anna

ZADD Pokemon:Leaderboard 0 zakariah

ZADD Pokemon:Leaderboard 0 bob

ZADD Pokemon:Leaderboard 0 mary

ZRANGE Command

All five members have been added successfully. Next, we should examine or query the added members using the ZRANGE command. The ZRANGE command allows retrieving members that are sorted in a given range. A range can be specified by rank, score, or lexicographical values.

Let’s query all the members by specifying the range by rank values.

ZRANGE Pokemon:Leaderboard 0 -1

As expected, all five members have been returned and ordered lexicographically because the score values are the same for all members at this point. In addition, 0 is the starting index/rank of the range, and -1 denotes the top index of the given ZSET.

The ZRANGE command offers a wide range of optional arguments, and we will use the WITHSCORES argument with the above command to display the associated scores for each member.

ZRANGE Pokemon:Leaderboard 0 -1 WITHSCORES

ZINCRBY Command

Assume that the players have been playing the game for some hours and scores have increased from 0. Redis ZSETs provide the ZINCRBY command to increment the scores of each member as follows.

ZINCRBY Pokemon:Leaderboard 100 bob

This should increment the value of the member bob from 0 to 100. Let’s call the same command to increment the scores of other players as well.

ZINCRBY Pokemon:Leaderboard 200 anna

ZINCRBY Pokemon:Leaderboard 76 zakariah

ZINCRBY Pokemon:Leaderboard 450 mary

ZINCRBY Pokemon:Leaderboard 167 john

As per the return values, scores should have been updated properly. Let’s use the ZRANGE command one time to retrieve the members again with their scores.

Bravo! Players’ scores have been properly updated. Furthermore, the members are ordered by their scores in ascending order which is a cool feature of Redis ZSETs.

ZREVRANK Command

It is a must to display the rank of each player on a leaderboard. So, the ZREVRANK command is used to show the rank of members where the element associated with the highest score will be the 0th rank, and next highest will be the 1st rank, and so on.

Since member mary has the highest score, that element should be ranked as the top member with 0th rank. Let’s use the ZREVRANK command as follows.

ZREVRANK Pokemon:Leaderboard mary

As expected, the rank is 0, which means the top player in the game leaderboard.

Let’s use the ZREVRANK command with the element zakariah as follows. Ideally, it should be the last rank since this member has the lowest score value.

ZREM Command

Whenever we need to remove an element or multiple elements from a ZSET, the ZREM command is useful. Let’s remove zakariah from the leaderboard due to his low score.

ZREM Pokemon:Leaderboard zakariah

It has been properly removed from the ZSET.

Most importantly, the ZSET commands have O(log(N)) time complexity, where N is the number of elements in the sorted set, which is considerably faster. At the same time, the ZRANGE command should be used with care because it has O(log(n) + l), where l is the number of results returned by the command. So, it might cause performance issues when working with larger data sets.

Conclusion

In summary, Redis ZSET is a short name for a sorted set data type that can hold unique members ordered by their score values. As discussed, the ZSET members are non-repeated strings, and score values can be repeated. When multiple members are assigned with the same score value, those members will be ordered lexicographically. ZSETs are a great choice for real-time leaderboards, secondary indexing, and priority queues with higher responsiveness and low latency in memory access. To conclude, several commands are available to add, remove, and query members from a given Redis ZSET with ease.

About the author

Nimesha Jinarajadasa

Being a Full-stack Senior Software Engineer for more than five years, I love technology, as technology has the power to solve our many problems within just a minute. I try to learn more and create more opportunities for this new world.