用Redis实现排行榜的详细用例

下面是一个使用 Redis 的 Sorted Set 数据结构实现的排行榜系统的详细示例,包括查看全部排名、获取单个排名、增加分数等操作。我们将使用 Lettuce 库来与 Redis 进行交互。

项目结构

  1. pom.xml:添加必要的依赖。
  2. LeaderBoardService:实现排行榜的功能。
  3. LeaderBoardApplication:测试排行榜功能。

第一步:添加必要的依赖

在你的 Maven 项目的 pom.xml 文件中添加 Lettuce 和 Spring Data Redis 的依赖:

xml 复制代码
<dependencies>
    <!-- Spring Boot Starter Web -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <!-- Spring Data Redis -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-redis</artifactId>
    </dependency>

    <!-- Lettuce dependency for Redis interaction -->
    <dependency>
        <groupId>io.lettuce.core</groupId>
        <artifactId>lettuce-core</artifactId>
        <version>6.1.5</version>
    </dependency>
</dependencies>

第二步:编写 LeaderBoardService 类

这个类实现所有与排行榜相关的操作,包括添加玩家、增加分数、查看全部排名和获取单个排名。

java 复制代码
import io.lettuce.core.RedisClient;
import io.lettuce.core.api.StatefulRedisConnection;
import io.lettuce.core.api.sync.RedisCommands;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class LeaderBoardService {
    private static final String LEADERBOARD_KEY = "game:leaderboard";
    private RedisClient redisClient;
    private StatefulRedisConnection<String, String> connection;
    private RedisCommands<String, String> commands;

    public LeaderBoardService() {
        this.redisClient = RedisClient.create("redis://localhost:6379");
        this.connection = redisClient.connect();
        this.commands = connection.sync();
    }

    // 添加或者更新玩家分数
    public void updatePlayerScore(String player, double score) {
        commands.zadd(LEADERBOARD_KEY, score, player);
    }

    // 增加玩家分数
    public void incrementPlayerScore(String player, double increment) {
        commands.zincrby(LEADERBOARD_KEY, increment, player);
    }

    // 获取玩家的排名(从0开始)
    public Long getPlayerRank(String player) {
        return commands.zrevrank(LEADERBOARD_KEY, player);
    }

    // 获取玩家的分数
    public Double getPlayerScore(String player) {
        return commands.zscore(LEADERBOARD_KEY, player);
    }

    // 获取全部排名列表
    public List<Map.Entry<String, Double>> getAllPlayers() {
        return commands.zrevrangeWithScores(LEADERBOARD_KEY, 0, -1)
                .stream()
                .map(entry -> new AbstractMap.SimpleEntry<>(entry.getValue(), entry.getScore()))
                .collect(Collectors.toList());
    }

    public void close() {
        connection.close();
        redisClient.shutdown();
    }

    public static void main(String[] args) {
        LeaderBoardService leaderBoardService = new LeaderBoardService();

        // 添加玩家和分数
        leaderBoardService.updatePlayerScore("player1", 500);
        leaderBoardService.updatePlayerScore("player2", 300);
        leaderBoardService.updatePlayerScore("player3", 400);
        
        // 增加玩家分数
        leaderBoardService.incrementPlayerScore("player2", 200);

        // 获取玩家排名
        Long rank = leaderBoardService.getPlayerRank("player2");
        System.out.println("Player2's rank: " + rank);

        // 获取玩家分数
        Double score = leaderBoardService.getPlayerScore("player2");
        System.out.println("Player2's score: " + score);

        // 获取全部排名列表
        List<Map.Entry<String, Double>> players = leaderBoardService.getAllPlayers();
        for (Map.Entry<String, Double> entry : players) {
            System.out.println("Player: " + entry.getKey() + ", Score: " + entry.getValue());
        }

        leaderBoardService.close();
    }
}

代码解释

1. 初始化 Redis 连接

使用 Lettuce 初始化 Redis 客户端连接:

java 复制代码
public LeaderBoardService() {
    this.redisClient = RedisClient.create("redis://localhost:6379");
    this.connection = redisClient.connect();
    this.commands = connection.sync();
}
2. 添加或更新玩家分数

使用 ZADD 命令添加或更新玩家的分数:

java 复制代码
public void updatePlayerScore(String player, double score) {
    commands.zadd(LEADERBOARD_KEY, score, player);
}
3. 增加玩家分数

使用 ZINCRBY 命令增加玩家的分数:

java 复制代码
public void incrementPlayerScore(String player, double increment) {
    commands.zincrby(LEADERBOARD_KEY, increment, player);
}
4. 获取玩家排名

使用 ZREVRANK 命令获取玩家的排名,排名是从0开始的:

java 复制代码
public Long getPlayerRank(String player) {
    return commands.zrevrank(LEADERBOARD_KEY, player);
}
5. 获取玩家分数

使用 ZSCORE 命令获取玩家的分数:

java 复制代码
public Double getPlayerScore(String player) {
    return commands.zscore(LEADERBOARD_KEY, player);
}
6. 获取全部排名列表

使用 ZREVRANGE 命令获取所有玩家的排名和分数:

java 复制代码
public List<Map.Entry<String, Double>> getAllPlayers() {
    return commands.zrevrangeWithScores(LEADERBOARD_KEY, 0, -1)
            .stream()
            .map(entry -> new AbstractMap.SimpleEntry<>(entry.getValue(), entry.getScore()))
            .collect(Collectors.toList());
}

第三步:编写 LeaderBoardApplication 类

main 方法中调用 LeaderBoardService 的方法,测试排行榜系统的功能。

java 复制代码
public class LeaderBoardApplication {

    public static void main(String[] args) {
        LeaderBoardService leaderBoardService = new LeaderBoardService();

        // 添加玩家和分数
        leaderBoardService.updatePlayerScore("player1", 500);
        leaderBoardService.updatePlayerScore("player2", 300);
        leaderBoardService.updatePlayerScore("player3", 400);
        
        // 增加玩家分数
        leaderBoardService.incrementPlayerScore("player2", 200);

        // 获取玩家排名
        Long rank = leaderBoardService.getPlayerRank("player2");
        System.out.println("Player2's rank: " + rank);

        // 获取玩家分数
        Double score = leaderBoardService.getPlayerScore("player2");
        System.out.println("Player2's score: " + score);

        // 获取全部排名列表
        List<Map.Entry<String, Double>> players = leaderBoardService.getAllPlayers();
        for (Map.Entry<String, Double> entry : players) {
            System.out.println("Player: " + entry.getKey() + ", Score: " + entry.getValue());
        }

        leaderBoardService.close();
    }
}

总结

通过上述步骤,我们实现了一个基于 Redis Sorted Set 的排行榜系统。该系统包括添加或更新玩家分数、增加玩家分数、获取单个玩家的排名和分数、查看全体玩家排名等功能。使用 Lettuce 库,我们能够高效地与 Redis 进行交互,实现高性能的实时排行榜系统。这个例子展示了 Redis Sorted Set 在实际应用场景中的强大能力。

相关推荐
菜鸟小九几秒前
redis基础(java客户端)
java·redis·bootstrap
不会写程序的未来程序员1 分钟前
Redis 哨兵(Sentinel)原理
数据库·redis·sentinel
阿海5742 分钟前
卸载redis7.2.4的shell脚本
linux·redis·shell
有什么东东4 分钟前
redis实现店铺类型查看
java·开发语言·redis
一字白首7 分钟前
Vue 项目实战,从组件缓存到 Vant UI 集成:项目初始化全流程
vue.js·ui·缓存
Lisonseekpan18 分钟前
技术选型分析:MySQL、Redis、MongoDB、ElasticSearch与大数据怎么选?
大数据·redis·后端·mysql·mongodb·elasticsearch
梁萌19 分钟前
MySQL关联查询原理与优化
数据库·mysql
⑩-19 分钟前
Spring 的事务传播行为(Propagation)
java·数据库·spring
綝~21 分钟前
Excel导入MongoDB操作手册
数据库·excel
xiaojianhx23 分钟前
Ubuntu24 安装 Redis 及常用命令
redis·ubuntu