在实际开发中,排行榜功能非常常见,比如游戏积分榜、用户活跃度排行、内容点赞数排行等。Redis 提供的 有序集合(Sorted Set,简称 ZSet) 非常适合实现排行榜功能,因为它既能存储成员(member),又能存储对应的分数(score),并且能够根据分数进行排序。
本文将通过 Go 语言结合 go-redis
库,实现一个简单的用户积分排行榜。
一、环境准备
-
安装 Redis 确保本地或服务器已经安装并启动了 Redis。
bashredis-server
-
安装 go-redis 库
bashgo 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 获取用户排名
这种方式既高效又简洁,适合用在游戏积分榜、活动竞赛榜单、内容点赞排行等场景中。