golang redis zset合并数据集
【摘要】 在 Go 中使用 Redis 将所有以 event_ 开头的 ZSET(有序集合)合并到 event_4 这个 ZSET 中,可以使用 Redis 的 ZUNIONSTORE 命令。步骤获取所有以 event_ 开头的 ZSET key(使用 KEYS 或 SCAN)。使用 ZUNIONSTORE 将这些 ZSET 合并到 event_4(event_4 可以...
在 Go 中使用 Redis 将所有以 event_
开头的 ZSET(有序集合)合并到 event_4
这个 ZSET 中,可以使用 Redis 的 ZUNIONSTORE
命令。
步骤
- 获取所有以
event_
开头的 ZSET key(使用KEYS
或SCAN
)。 - 使用
ZUNIONSTORE
将这些 ZSET 合并到event_4
(event_4
可以是一个已存在的 ZSET,也可以是新创建的)。
1. 使用 KEYS
获取所有 event_
开头的 ZSET key(不推荐生产环境使用)
KEYS
命令会阻塞 Redis,不推荐在生产环境使用,仅适用于测试或小规模数据。
Go 代码示例
package main
import (
"context"
"fmt"
"github.com/redis/go-redis/v9"
)
func main() {
rdb := redis.NewClient(&redis.Options{
Addr: "localhost:6379", // Redis 地址
})
ctx := context.Background()
// 1. 获取所有以 "event_" 开头的 key
keys, err := rdb.Keys(ctx, "event_*").Result()
if err != nil {
panic(err)
}
// 2. 过滤出 ZSET 类型的 key(可选,确保 key 是 ZSET)
var zsetKeys []string
for _, key := range keys {
keyType, err := rdb.Type(ctx, key).Result()
if err != nil {
panic(err)
}
if keyType == "zset" {
zsetKeys = append(zsetKeys, key)
}
}
// 3. 如果没有符合条件的 ZSET,直接返回
if len(zsetKeys) == 0 {
fmt.Println("没有找到以 'event_' 开头的 ZSET")
return
}
// 4. 使用 ZUNIONSTORE 合并到 event_4
// 参数:destinationKey, numKeys, sourceKeys...
err = rdb.ZUnionStore(ctx, "event_4", redis.ZStore{
Weights: nil, // 默认权重 1
}, zsetKeys...).Err()
if err != nil {
panic(err)
}
fmt.Printf("成功合并 %d 个 ZSET 到 event_4\n", len(zsetKeys))
}
2. 使用 SCAN
获取所有 event_
开头的 ZSET key(推荐生产环境使用)
SCAN
是 非阻塞 的,适合生产环境使用,避免 KEYS
导致的性能问题。
Go 代码示例
package main
import (
"context"
"fmt"
"github.com/redis/go-redis/v9"
)
func main() {
rdb := redis.NewClient(&redis.Options{
Addr: "localhost:6379", // Redis 地址
})
ctx := context.Background()
// 1. 使用 SCAN 遍历所有以 "event_" 开头的 key
var zsetKeys []string
var cursor uint64
for {
keys, nextCursor, err := rdb.Scan(ctx, cursor, "event_*", 100).Result() // 每次扫描 100 个 key
if err != nil {
panic(err)
}
// 2. 过滤出 ZSET 类型的 key
for _, key := range keys {
keyType, err := rdb.Type(ctx, key).Result()
if err != nil {
panic(err)
}
if keyType == "zset" {
zsetKeys = append(zsetKeys, key)
}
}
// 3. 如果 cursor 回到 0,说明扫描完成
if nextCursor == 0 {
break
}
cursor = nextCursor
}
// 4. 如果没有符合条件的 ZSET,直接返回
if len(zsetKeys) == 0 {
fmt.Println("没有找到以 'event_' 开头的 ZSET")
return
}
// 5. 使用 ZUNIONSTORE 合并到 event_4
err := rdb.ZUnionStore(ctx, "event_4", redis.ZStore{
Weights: nil, // 默认权重 1
}, zsetKeys...).Err()
if err != nil {
panic(err)
}
fmt.Printf("成功合并 %d 个 ZSET 到 event_4\n", len(zsetKeys))
}
3. 使用 ZUNIONSTORE
合并 ZSET 的注意事项
-
ZUNIONSTORE
会创建一个新的 ZSET(如果destinationKey
不存在)或覆盖已有的 ZSET(如果destinationKey
已存在)。 -
Weights
参数:可以指定每个源 ZSET 的权重(默认nil
表示权重 1)。 -
Aggregate
参数:可以指定合并方式(SUM
、MIN
、MAX
),默认SUM
。
示例:带权重的合并
err = rdb.ZUnionStore(ctx, "event_4", redis.ZStore{
Weights: []float64{1, 2, 3}, // 每个源 ZSET 的权重
Aggregate: "SUM", // 合并方式(SUM/MIN/MAX)
}, zsetKeys...).Err()
4. 完整代码(推荐 SCAN
方式)
package main
import (
"context"
"fmt"
"github.com/redis/go-redis/v9"
)
func main() {
rdb := redis.NewClient(&redis.Options{
Addr: "localhost:6379", // Redis 地址
})
ctx := context.Background()
// 1. 使用 SCAN 获取所有以 "event_" 开头的 ZSET key
var zsetKeys []string
var cursor uint64
for {
keys, nextCursor, err := rdb.Scan(ctx, cursor, "event_*", 100).Result()
if err != nil {
panic(err)
}
for _, key := range keys {
keyType, err := rdb.Type(ctx, key).Result()
if err != nil {
panic(err)
}
if keyType == "zset" {
zsetKeys = append(zsetKeys, key)
}
}
if nextCursor == 0 {
break
}
cursor = nextCursor
}
if len(zsetKeys) == 0 {
fmt.Println("没有找到以 'event_' 开头的 ZSET")
return
}
// 2. 合并到 event_4
err := rdb.ZUnionStore(ctx, "event_4", redis.ZStore{
Weights: nil, // 默认权重 1
Aggregate: "SUM", // 默认 SUM
}, zsetKeys...).Err()
if err != nil {
panic(err)
}
fmt.Printf("成功合并 %d 个 ZSET 到 event_4\n", len(zsetKeys))
}
5. 测试
- 准备数据:
# 添加几个测试 ZSET ZADD event_1 1 "item1" 2 "item2" ZADD event_2 3 "item3" 4 "item4" ZADD event_3 5 "item5" 6 "item6"
- 运行 Go 程序:
go run main.go
- 检查
event_4
:
预期输出:ZRANGE event_4 0 -1 WITHSCORES
1) "item1" 2) "1" 3) "item2" 4) "2" 5) "item3" 6) "3" 7) "item4" 8) "4" 9) "item5" 10) "5" 11) "item6" 12) "6"
总结
方法 | 适用场景 | 推荐度 |
---|---|---|
KEYS |
测试环境,小数据量 | ❌ 不推荐生产环境 |
SCAN |
生产环境,大数据量 | ✅ 推荐 |
ZUNIONSTORE |
合并 ZSET | ✅ 必须使用 |
推荐使用 SCAN
+ ZUNIONSTORE
的方式,避免 KEYS
阻塞 Redis,并确保正确合并 ZSET 数据。 🚀
【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)