用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 在实际应用场景中的强大能力。

相关推荐
准时准点睡觉29 分钟前
window安装MYSQL5.5出错:a windows service with the name MYSQL alreadyexists....
数据库·windows·mysql
天硕国产存储技术站1 小时前
国产固态硬盘推荐:天硕工业级SSDDRAM缓存与HMB技术详解
缓存·固态硬盘·国产ssd·国产ssd品牌
Zhangzy@1 小时前
Rust 内存对齐与缓存友好设计
spring·缓存·rust
无敌最俊朗@1 小时前
SQlite:外键约束
数据库·oracle
金仓拾光集2 小时前
金仓替代MongoDB:安全与性能协同提升——社交用户画像系统的国产化实践
数据库·安全·mongodb·kingbase·kingbasees·数据库平替用金仓·金仓数据库
FinTech老王2 小时前
国产数据库替换MongoDB实战:浙江人民医院电子病历系统国产化升级案例
数据库·mongodb
l1t2 小时前
在Lua用luasql-sqlite3库访问SQLite数据库
数据库·git·sqlite·lua
喆星时瑜2 小时前
Windows图标修复--缓存重建教程
windows·缓存
qq_300240632 小时前
spring cache 支持多结构的 Redis 缓存管理器
spring·缓存
2501_938780283 小时前
《轨道交通检测系统中 Qt 与数据库交互的优化方案》
数据库·qt·交互