Redis核心应用场景及代码案例
1.高频数据缓存
缓存数据库查询结果、API 响应等高频访问数据,减少后端服务压力,典型场景如电商商品详情页、用户信息缓存。
// 1. 高频数据缓存
func cacheExample() {key := "product:1001"// 尝试从缓存获取val, err := rdb.Get(ctx, key).Result()if err == redis.Nil {// 缓存未命中,从数据库获取并设置缓存dbVal := "iPhone 13, 5999元" // 模拟数据库查询err := rdb.Set(ctx, key, dbVal, 10*time.Minute).Err()if err != nil {panic(err)}val = dbVal} else if err != nil {panic(err)}fmt.Printf("商品信息: %s\n", val)
}
2.分布式会话存储
在分布式系统中,将用户会话(Session)数据存储到 Redis,实现多服务节点间会话共享,避免登录状态丢失。
// 2. 分布式会话存储
func sessionExample() {sessionID := "session:user123"userData := `{"user_id":123, "username":"testuser"}`// 设置会话,2小时过期err := rdb.Set(ctx, sessionID, userData, 2*time.Hour).Err()if err != nil {panic(err)}// 获取会话session, err := rdb.Get(ctx, sessionID).Result()if err != nil {panic(err)}fmt.Printf("会话数据: %s\n", session)
}
3.计数器
利用INCR
/DECR
等原子命令,实现高并发下的计数器功能,如文章阅读量、视频播放量、接口调用次数统计。
// 3. 计数器
func counterExample() {articleID := "article:456"// 阅读量+1count, err := rdb.Incr(ctx, articleID+":views").Result()if err != nil {panic(err)}fmt.Printf("文章阅读量: %d\n", count)
}
4.限流器
基于 Redis 的INCR
+ 过期时间(EXPIRE
)或Redis-Cell
模块,实现接口 QPS 限流、用户行为频率限制(如短信验证码 60 秒内 1 次)。
// 4. 限流器
func rateLimiterExample(userID string) bool {key := fmt.Sprintf("rate_limit:%s", userID)// 60秒内最多5次请求count, err := rdb.Incr(ctx, key).Result()if err != nil {panic(err)}// 第一次设置过期时间if count == 1 {rdb.Expire(ctx, key, 60*time.Second)}// 超过限制if count > 5 {return false}return true
}
5.分布式锁
通过SET NX EX
(不存在则设置 + 过期时间)命令实现分布式锁,解决多服务并发操作共享资源的冲突问题(如库存扣减)。
// 5. 分布式锁
func distributedLockExample(resource string) bool {key := fmt.Sprintf("lock:%s", resource)// 尝试获取锁,设置10秒过期防止死锁ok, err := rdb.SetNX(ctx, key, "locked", 10*time.Second).Result()if err != nil {panic(err)}return ok
}// 释放锁
func releaseLock(resource string) {key := fmt.Sprintf("lock:%s", resource)rdb.Del(ctx, key)
}
6.消息队列
利用List
的LPUSH
(入队)和BRPOP
(阻塞出队)命令实现简单消息队列,或用Pub/Sub
实现广播式消息传递(如系统通知)。
// 6. 消息队列
func messageQueueExample() {queue := "message_queue"// 生产者:发送消息err := rdb.LPush(ctx, queue, "message1").Err()if err != nil {panic(err)}// 消费者:接收消息(阻塞式)msg, err := rdb.BRPop(ctx, 0*time.Second, queue).Result()if err != nil {panic(err)}fmt.Printf("收到消息: %s\n", msg[1])
}
7.排行榜
基于Sorted Set
(有序集合)的分数排序特性,实现实时排行榜,如游戏积分榜、商品销量榜、用户贡献榜。
// 7. 排行榜
func rankingExample() {rankKey := "game_ranking"// 添加玩家分数rdb.ZAdd(ctx, rankKey, &redis.Z{Score: 95, Member: "player1"})rdb.ZAdd(ctx, rankKey, &redis.Z{Score: 88, Member: "player2"})rdb.ZAdd(ctx, rankKey, &redis.Z{Score: 99, Member: "player3"})// 获取前三名(从高到低)result, err := rdb.ZRevRangeWithScores(ctx, rankKey, 0, 2).Result()if err != nil {panic(err)}fmt.Println("排行榜前三名:")for i, z := range result {fmt.Printf("%d. %s: %.0f分\n", i+1, z.Member, z.Score)}
}
8.热点数据存储
存储实时热点数据(如实时热搜、热门商品 TOP10),利用 Redis 高性能读写能力支撑高并发访问。
// 8. 热点数据存储
func hotDataExample() {// 存储热搜词hotKey := "hot_search"rdb.SAdd(ctx, hotKey, "世界杯", "冬奥会", "科技新闻")// 获取所有热点数据hots, err := rdb.SMembers(ctx, hotKey).Result()if err != nil {panic(err)}fmt.Println("热点数据:", hots)
}
9.延迟任务队列
通过Sorted Set
将任务到期时间作为分数,定期扫描获取到期任务,实现延迟执行(如订单 30 分钟未支付自动取消)。
// 9. 延迟任务队列
func delayQueueExample() {delayKey := "delay_queue"// 30分钟后执行的任务(时间戳作为分数)execTime := time.Now().Add(30 * time.Minute).Unix()rdb.ZAdd(ctx, delayKey, &redis.Z{Score: float64(execTime), Member: "order:cancel:10086"})// 处理到期任务(实际应用中会定时执行)now := time.Now().Unix()tasks, err := rdb.ZRangeByScore(ctx, delayKey, &redis.ZRangeBy{Min: "0",Max: fmt.Sprintf("%d", now),}).Result()if err != nil {panic(err)}fmt.Println("需要处理的延迟任务:", tasks)// 处理完成后删除if len(tasks) > 0 {rdb.ZRemRangeByScore(ctx, delayKey, "0", fmt.Sprintf("%d", now))}
}
10.地理位置服务(LBS)
利用Geo
类型(如GEOADD
/GEORADIUS
)存储地理位置坐标,实现附近商家搜索、用户定位匹配等功能。
// 10. 地理位置服务
func geoExample() {geoKey := "restaurants"// 添加地理位置(经度,纬度,名称)rdb.GeoAdd(ctx, geoKey, &redis.GeoLocation{Name: "KFC",Longitude: 116.403874,Latitude: 39.914885,})// 查找附近1公里内的餐厅result, err := rdb.GeoRadius(ctx, geoKey, 116.404, 39.915, &redis.GeoRadiusQuery{Radius: 1,Unit: "km",WithDistance: true,}).Result()if err != nil {panic(err)}fmt.Println("附近的餐厅:")for _, loc := range result {fmt.Printf("%s: 距离%.2f公里\n", loc.Name, loc.Distance)}
}
11.布隆过滤器(Bloom Filter)
基于 Redis 的Bloom Filter
模块,快速判断数据是否存在,用于缓存穿透防护、海量数据去重(如过滤已读消息)。
// 11. 布隆过滤器(需要Redis Bloom模块)
func bloomFilterExample() {filterKey := "user_seen"// 添加已读用户rdb.Do(ctx, "BF.ADD", filterKey, "user:100")rdb.Do(ctx, "BF.ADD", filterKey, "user:200")// 检查用户是否已读result, _ := rdb.Do(ctx, "BF.EXISTS", filterKey, "user:100").Int64()fmt.Printf("用户100是否已读: %v\n", result == 1)result, _ = rdb.Do(ctx, "BF.EXISTS", filterKey, "user:300").Int64()fmt.Printf("用户300是否已读: %v\n", result == 1)
}
12.BitMap(位存储)
用SETBIT
/GETBIT
操作二进制位,实现高效的布尔型数据存储,如用户签到记录(1 年仅需 365 位,约 46 字节 / 用户)、活跃用户标记。
// 12. BitMap
func bitmapExample() {userID := "user:sign:123"// 标记第1天和第3天签到rdb.SetBit(ctx, userID, 1, 1)rdb.SetBit(ctx, userID, 3, 1)// 检查第1天是否签到signed, _ := rdb.GetBit(ctx, userID, 1).Result()fmt.Printf("第1天是否签到: %v\n", signed == 1)// 统计签到次数count, _ := rdb.BitCount(ctx, userID, nil).Result()fmt.Printf("总签到次数: %d\n", count)
}
13.HyperLogLog
基于概率数据结构,用极小内存统计海量数据的基数(不重复元素个数),如 UV(独立访客)统计、APP 日活用户计数。
// 13. HyperLogLog
func hyperLogLogExample() {uvKey := "page:uv:home"// 记录访问用户rdb.PFAdd(ctx, uvKey, "user1", "user2", "user3")rdb.PFAdd(ctx, uvKey, "user2", "user3", "user4")// 统计独立访客数count, _ := rdb.PFCount(ctx, uvKey).Result()fmt.Printf("独立访客数: %d\n", count)
}
14.数据共享与传递
作为分布式系统的 “数据中转站”,存储临时共享数据,如微服务间的参数传递、跨服务任务状态同步。
// 14. 数据共享与传递
func dataSharingExample() {transferKey := "service:transfer:task123"// 服务A设置数据rdb.HSet(ctx, transferKey, map[string]interface{}{"status": "processing","result": "",})// 服务B获取并更新数据status, _ := rdb.HGet(ctx, transferKey, "status").Result()fmt.Printf("任务状态: %s\n", status)rdb.HSet(ctx, transferKey, "status", "completed")rdb.HSet(ctx, transferKey, "result", "success")
}
15.购物车
用Hash
类型存储用户购物车数据(键:用户 ID,字段:商品 ID,值:数量),支持快速添加、修改、删除商品,且性能高效。
// 15. 购物车
func shoppingCartExample(userID string) {cartKey := fmt.Sprintf("cart:%s", userID)// 添加商品rdb.HSet(ctx, cartKey, "product:1001", 2) // 2件商品1001rdb.HSet(ctx, cartKey, "product:2002", 1) // 1件商品2002// 获取购物车cart, _ := rdb.HGetAll(ctx, cartKey).Result()fmt.Printf("%s的购物车: %v\n", userID, cart)// 更新数量rdb.HIncrBy(ctx, cartKey, "product:1001", 1)
}
16.分布式 ID 生成器
利用INCR
命令生成全局唯一、有序的 ID,结合前缀(如业务标识)和时间戳,满足订单 ID、日志 ID 等场景的唯一性需求。
// 16. 分布式ID生成器
func idGeneratorExample(business string) string {key := fmt.Sprintf("id:generator:%s", business)// 生成IDid, _ := rdb.Incr(ctx, key).Result()// 组合业务前缀和时间戳return fmt.Sprintf("%s_%d_%d", business, time.Now().Unix(), id)
}
代码初始化与测试案例:
import ("context""fmt""time""github.com/go-redis/redis/v8"
)var ctx = context.Background()
var rdb *redis.Client// 初始化Redis连接
func initRedis() {rdb = redis.NewClient(&redis.Options{Addr: "localhost:6379",Password: "", // 无密码DB: 0, // 默认DB})
}func main() {initRedis()// 运行示例cacheExample()sessionExample()counterExample()fmt.Printf("限流检查: %v\n", rateLimiterExample("user123"))if distributedLockExample("inventory:100") {defer releaseLock("inventory:100")fmt.Println("获取锁成功,执行操作")}messageQueueExample()rankingExample()hotDataExample()delayQueueExample()geoExample()bloomFilterExample()bitmapExample()hyperLogLogExample()dataSharingExample()shoppingCartExample("user:123")fmt.Printf("生成订单ID: %s\n", idGeneratorExample("order"))
}