redis 排行榜实现

本文介绍了如何利用Redis的ZSet特性来实现排行榜功能,通过ZADD命令添加或更新权重值,使用ZRANG命令获取指定范围的排名,以及ZRANK查询成员的排名,强调了Redis在处理此类排序需求上的高效性和适用性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

想起在上一家公司做的一个需求,类似做个用户的中奖状况的滚动条(比如取出前20名来滚动),中奖用户根据中奖状况排序,当时数据存在mongodb中,各种aggregation和排序,现在想想其实本质是个排行榜,完全可以用redis来实现这个排行榜。

redis中的zset保证元素的唯一性以及有序性

zadd命令如上,增加或者修改命令

ranking是key 数字是score权重值,

zrang KEY start end 显示排名,zrang KEY 0 -1 显示所有排名(score值越小排在越前面

查询某个value排名 zrank KEY MEMBER(排名第一是0)

@Autowired
    private RedisU
### 使用 Redis 和 `RedisTemplate` 实现排行榜 (Leaderboard) 功能 #### 配置 Redis 连接池和数据源 为了确保应用程序能够高效地访问 Redis,需要在 `application.yml` 文件中配置 Redis 的连接参数: ```yaml spring: data: redis: host: localhost port: 6379 password: redis123456 lettuce: pool: max-active: 100 max-idle: 50 min-idle: 10 ``` 此配置定义了 Redis 主机地址、端口号以及连接池的最大活动连接数等属性[^3]。 #### 创建排行榜服务接口和服务实现类 创建一个名为 `ILeaderboardService` 接口及其默认实现类 `LeaderboardServiceImpl` 来管理排行榜逻辑。该服务负责向 Redis 中存储用户得分并查询排名情况。 ```java public interface ILeaderboardService { void addOrUpdateUserScore(String userId, double score); Set<Tuple> getTopNUsers(int n); } ``` 接着,在其实现类中注入 `RedisTemplate<String, Object>` 并利用其操作有序集合的方法完成具体业务需求: ```java @Service public class LeaderboardServiceImpl implements ILeaderboardService { private static final String LEADERBOARD_KEY = "leaderboard"; @Autowired private RedisTemplate<String, Object> redisTemplate; /** * 添加或更新用户的分数到排行榜中 */ @Override public void addOrUpdateUserScore(String userId, double score) { redisTemplate.opsForZSet().add(LEADERBOARD_KEY, userId, score); } /** * 获取前 N 名用户的信息(含分数) */ @Override public Set<Tuple> getTopNUsers(int n) { return redisTemplate.opsForZSet().reverseRangeWithScores(LEADERBOARD_KEY, 0, n - 1); } } ``` 上述代码片段展示了如何使用 `RedisTemplate` 对象中的 `opsForZSet()` 方法来进行 ZSET 类型的操作,从而实现了对排行榜的增删改查功能[^1]。 #### 定义控制器暴露 RESTful API 为了让外部应用可以通过 HTTP 请求与排行榜交互,还需要编写相应的 Controller 层代码来接收请求并将结果返回给客户端。 ```java @RestController @RequestMapping("/api/leaderboards") public class LeaderboardController { @Autowired private ILeaderboardService leaderboardService; @PostMapping("/update/{userId}") public ResponseEntity<Void> updateUserScore(@PathVariable String userId, @RequestParam Double score) { if (score != null && !Double.isNaN(score)) { leaderboardService.addOrUpdateUserScore(userId, score); return new ResponseEntity<>(HttpStatus.CREATED); } else { throw new IllegalArgumentException("Invalid Score Value"); } } @GetMapping("/top/{n}") public List<Map.Entry<String, Double>> fetchTopNUsers(@PathVariable int n) { Set<ZSetOperations.TypedTuple<Object>> topEntries = leaderboardService.getTopNUsers(n); List<Map.Entry<String, Double>> result = new ArrayList<>(); for (var entry : topEntries) { Map.Entry<String, Double> userEntry = new AbstractMap.SimpleEntry<> ((String)entry.getValue(), entry.getScore()); result.add(userEntry); } return result; } } ``` 这段 Java Web 控制器提供了两个主要的 API 端点:一个是用来提交新成绩;另一个则是获取指定数量内的最高分玩家列表[^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值