Go语言实战案例- Redis实现简单排行榜

在实际开发中,排行榜功能非常常见,比如游戏积分榜、用户活跃度排行、内容点赞数排行等。Redis 提供的 有序集合(Sorted Set,简称 ZSet) 非常适合实现排行榜功能,因为它既能存储成员(member),又能存储对应的分数(score),并且能够根据分数进行排序。

本文将通过 Go 语言结合 go-redis 库,实现一个简单的用户积分排行榜。


一、环境准备

  1. 安装 Redis 确保本地或服务器已经安装并启动了 Redis。

    bash 复制代码
    redis-server
  2. 安装 go-redis 库

    bash 复制代码
    go get github.com/redis/go-redis/v9

二、排行榜核心操作

Redis ZSet 常用命令:

  • ZADD:添加成员及其分数
  • ZINCRBY:为成员增加分数
  • ZREVRANGE:获取分数最高的前 N 个成员(倒序)
  • ZRANK:获取某个成员的排名(正序,0 为第一名)
  • ZREVRANK:获取某个成员的倒序排名

三、代码实现

1. 连接 Redis

go 复制代码
package main

import (
	"context"
	"fmt"
	"github.com/redis/go-redis/v9"
)

var ctx = context.Background()

func initRedis() *redis.Client {
	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379", // Redis 地址
		Password: "",               // 无密码可留空
		DB:       0,                // 默认 DB
	})
	return rdb
}

2. 添加用户积分

go 复制代码
// 添加用户积分
func addScore(rdb *redis.Client, key string, user string, score float64) error {
	// ZADD leaderboard user score
	return rdb.ZAdd(ctx, key, redis.Z{
		Score:  score,
		Member: user,
	}).Err()
}

3. 增加用户积分

go 复制代码
// 增加用户积分
func incrScore(rdb *redis.Client, key string, user string, delta float64) error {
	// ZINCRBY leaderboard delta user
	return rdb.ZIncrBy(ctx, key, delta, user).Err()
}

4. 获取前 N 名排行榜

go 复制代码
// 获取前 N 名
func getTopN(rdb *redis.Client, key string, n int64) ([]redis.Z, error) {
	// ZREVRANGE leaderboard 0 N-1 WITHSCORES
	return rdb.ZRevRangeWithScores(ctx, key, 0, n-1).Result()
}

5. 获取用户排名和积分

go 复制代码
// 获取用户排名(倒序)
func getUserRank(rdb *redis.Client, key string, user string) (int64, float64, error) {
	// 获取排名
	rank, err := rdb.ZRevRank(ctx, key, user).Result()
	if err != nil {
		return -1, 0, err
	}
	// 获取分数
	score, err := rdb.ZScore(ctx, key, user).Result()
	if err != nil {
		return -1, 0, err
	}
	return rank, score, nil
}

6. 主函数测试

go 复制代码
func main() {
	rdb := initRedis()
	key := "game:leaderboard"

	// 添加初始积分
	_ = addScore(rdb, key, "Alice", 100)
	_ = addScore(rdb, key, "Bob", 80)
	_ = addScore(rdb, key, "Charlie", 120)

	// 增加积分
	_ = incrScore(rdb, key, "Bob", 50)

	// 获取前 3 名
	top3, _ := getTopN(rdb, key, 3)
	fmt.Println("Top 3 Leaderboard:")
	for i, z := range top3 {
		fmt.Printf("%d. %s (score: %.0f)\n", i+1, z.Member, z.Score)
	}

	// 查询用户排名
	rank, score, _ := getUserRank(rdb, key, "Bob")
	fmt.Printf("Bob 排名: %d, 积分: %.0f\n", rank+1, score)
}

四、运行结果示例

假设运行后输出如下:

less 复制代码
Top 3 Leaderboard:
1. Charlie (score: 120)
2. Bob (score: 130)
3. Alice (score: 100)
Bob 排名: 2, 积分: 130

说明排行榜逻辑正常运行。


五、总结

通过 Redis 的有序集合(ZSet),我们可以快速高效地实现排行榜功能:

  • ZADD 添加用户与分数
  • ZINCRBY 更新用户分数
  • ZREVRANGE 获取前 N 名
  • ZREVRANK 获取用户排名

这种方式既高效又简洁,适合用在游戏积分榜、活动竞赛榜单、内容点赞排行等场景中。


相关推荐
打工的小王18 分钟前
Spring Boot(三)Spring Boot整合SpringMVC
java·spring boot·后端
80530单词突击赢2 小时前
JavaWeb进阶:SpringBoot核心与Bean管理
java·spring boot·后端
爬山算法2 小时前
Hibernate(87)如何在安全测试中使用Hibernate?
java·后端·hibernate
WeiXiao_Hyy2 小时前
成为 Top 1% 的工程师
java·开发语言·javascript·经验分享·后端
苏渡苇2 小时前
优雅应对异常,从“try-catch堆砌”到“设计驱动”
java·后端·设计模式·学习方法·责任链模式
long3163 小时前
Aho-Corasick 模式搜索算法
java·数据结构·spring boot·后端·算法·排序算法
rannn_1113 小时前
【苍穹外卖|Day4】套餐页面开发(新增套餐、分页查询、删除套餐、修改套餐、起售停售)
java·spring boot·后端·学习
短剑重铸之日3 小时前
《设计模式》第十一篇:总结
java·后端·设计模式·总结
Dragon Wu4 小时前
Spring Security Oauth2.1 授权码模式实现前后端分离的方案
java·spring boot·后端·spring cloud·springboot·springcloud
一个有梦有戏的人5 小时前
Python3基础:进阶基础,筑牢编程底层能力
后端·python