Welcome to the next exciting part of our Redis-based backend system project. In this unit, we will focus on building leaderboard functionality using Redis's sorted sets. Building a leaderboard is a popular use case for many applications, such as games and competitive platforms. You’ve got a good grasp of managing user data from previous lessons, so let’s build on that foundation.
A leaderboard is a vital feature in competitive applications like games, designed to rank users based on specific metrics such as scores or achievements. It fosters motivation and competition among users. In this unit, our primary focus will be:
- Adding user scores to a leaderboard: We will store user scores using Redis sorted sets with
hiredis
. - Retrieving the leaderboard: We will fetch and display the top users and their scores.
- Getting a user's rank and score: We will retrieve the ranking and score of a specific user.
Below are some key parts of the C++ code you will be working with to perform these tasks.
C++1#include <iostream> 2#include <hiredis/hiredis.h> 3 4int main() { 5 // Connect to Redis 6 redisContext* context = redisConnect("127.0.0.1", 6379); 7 if (context == nullptr || context->err) { 8 if (context) { 9 std::cerr << "Error: " << context->errstr << std::endl; 10 redisFree(context); 11 } else { 12 std::cerr << "Can't allocate redis context" << std::endl; 13 } 14 return 1; 15 } 16 17 // Add scores to the leaderboard 18 redisCommand(context, "ZADD leaderboard 100 user1"); 19 redisCommand(context, "ZADD leaderboard 200 user2"); 20 redisCommand(context, "ZADD leaderboard 150 user3"); 21 22 // Retrieve the leaderboard 23 redisReply* reply = (redisReply*) redisCommand(context, "ZREVRANGE leaderboard 0 2 WITHSCORES"); 24 if (reply->type == REDIS_REPLY_ARRAY) { 25 for (size_t i = 0; i < reply->elements; i += 2) { 26 std::cout << reply->element[i]->str << ": " << reply->element[i+1]->str << std::endl; 27 } 28 } 29 freeReplyObject(reply); 30 // Output: 31 // user2: 200 32 // user3: 150 33 // user1: 100 34 35 // Get rank and score of user3 36 reply = (redisReply*) redisCommand(context, "ZREVRANK leaderboard user3"); 37 if (reply->type == REDIS_REPLY_INTEGER) { 38 std::cout << "Rank of user3: " << reply->integer << std::endl; 39 } 40 freeReplyObject(reply); 41 // Output: 42 // Rank of user3: 1 43 44 reply = (redisReply*) redisCommand(context, "ZSCORE leaderboard user3"); 45 if (reply->type == REDIS_REPLY_STRING) { 46 std::cout << "Score of user3: " << reply->str << std::endl; 47 } 48 freeReplyObject(reply); 49 // Output: 50 // Score of user3: 150 51 52 // Clean up 53 redisFree(context); 54 return 0; 55}
This example demonstrates how to add a score for a user, retrieve the top scores, and fetch a user’s rank and score using C++. You are familiar with the ZADD
and ZREVRANGE
commands. These commands are used to add scores and retrieve the leaderboard, respectively.
Let's break down the Redis commands used here. The ZREVRANK
command returns the rank of a member in a sorted set, with the highest score being ranked first. The ZSCORE
command retrieves the score of a member in a sorted set. In C++, hiredis
commands provide results that require handling specific struct types and members, such as REDIS_REPLY_INTEGER
for ranks and REDIS_REPLY_STRING
for scores. After executing these commands, remember to free unused resources to prevent memory leaks.
Now that you have an overview, you can start implementing these components in your own projects, enhancing your Redis-based leaderboard features.