Appearance
Redis 必知必会
使用 Docker 启动 Redis
bash
docker run -d --name redis -p 6379:6379 redis:latest验证 Redis 容器
bash
docker exec -it redis redis-cli
set test "hello"
get test实现排行榜
Details
功能包括:
- 用户加分(ZINCRBY)
- 查询前 N 名(ZREVRANGE)
- 查询用户排名与分数(ZREVRANK + ZSCORE)排行榜
go
package main
import (
"context"
"fmt"
"github.com/redis/go-redis/v9"
"log"
)
var (
ctx = context.Background()
redisCli *redis.Client
)
const rankKey = "game:rank" // 排行榜 Key
// 初始化 Redis 客户端
func initRedis() {
redisCli = redis.NewClient(&redis.Options{
Addr: "127.0.0.1:6379",
Password: "", // 如果有密码记得加上
DB: 0,
})
if err := redisCli.Ping(ctx).Err(); err != nil {
log.Fatalf("Redis连接失败: %v", err)
}
}
// 给用户增加分数
func addScore(userID string, score float64) {
err := redisCli.ZIncrBy(ctx, rankKey, score, userID).Err()
if err != nil {
log.Printf("增加分数失败: %v", err)
}
fmt.Printf("✅ 用户 %s 增加 %.2f 分\n", userID, score)
}
// 获取排行榜前 N 名
func getTopN(n int64) {
res, err := redisCli.ZRevRangeWithScores(ctx, rankKey, 0, n-1).Result()
if err != nil {
log.Printf("获取排行榜失败: %v", err)
return
}
fmt.Printf("🏆 前 %d 名排行榜:\n", n)
for i, z := range res {
fmt.Printf("%d. 用户: %s, 分数: %.2f\n", i+1, z.Member.(string), z.Score)
}
}
// 获取某个用户排名和分数
func getUserRank(userID string) {
rank, err := redisCli.ZRevRank(ctx, rankKey, userID).Result()
if err == redis.Nil {
fmt.Println("用户未上榜")
return
}
if err != nil {
log.Printf("获取排名失败: %v", err)
return
}
score, _ := redisCli.ZScore(ctx, rankKey, userID).Result()
fmt.Printf("🎯 用户 %s 排名: %d, 分数: %.2f\n", userID, rank+1, score)
}
func main() {
initRedis()
// 模拟加分
addScore("user_1", 120)
addScore("user_2", 300)
addScore("user_3", 250)
addScore("user_1", 80) // 再加一次,累计分数
// 查看前 3 名
getTopN(3)
// 查看某用户排名
getUserRank("user_1")
}其它
- 数据类型:string、hash、list、set、zset
- 缓存问题:缓存击穿、缓存穿透、缓存雪崩、缓存预热
- 缓存更新 先更新数据库,再删缓存
- 分布式锁 set nx ex;解锁先判断 value 是否一致再 del