feat: redis读取hgetall数据批量读取返回

This commit is contained in:
TsMask
2024-11-07 20:52:48 +08:00
parent 7f4a8abcdd
commit 4a8f6e08ff
3 changed files with 109 additions and 26 deletions

View File

@@ -4,6 +4,7 @@ import (
"context" "context"
"fmt" "fmt"
"strings" "strings"
"sync"
"time" "time"
"be.ems/src/framework/config" "be.ems/src/framework/config"
@@ -179,31 +180,22 @@ func GetExpire(source string, key string) (float64, error) {
} }
// 获得缓存数据的key列表 // 获得缓存数据的key列表
func GetKeys(source string, pattern string) ([]string, error) { func GetKeys(source string, match string) ([]string, error) {
// 数据源 // 数据源
rdb := DefaultRDB() rdb := DefaultRDB()
if source != "" { if source != "" {
rdb = RDB(source) rdb = RDB(source)
} }
// 初始化变量 keys := make([]string, 0)
var keys []string
var cursor uint64 = 0
ctx := context.Background() ctx := context.Background()
// 循环遍历获取匹配的键 iter := rdb.Scan(ctx, 0, match, 1000).Iterator()
for { if err := iter.Err(); err != nil {
// 使用 SCAN 命令获取匹配的键 logger.Errorf("Failed to scan keys: %v", err)
batchKeys, nextCursor, err := rdb.Scan(ctx, cursor, pattern, 1000).Result() return keys, err
if err != nil { }
logger.Errorf("Failed to scan keys: %v", err) for iter.Next(ctx) {
return keys, err keys = append(keys, iter.Val())
}
cursor = nextCursor
keys = append(keys, batchKeys...)
// 当 cursor 为 0表示遍历完成
if cursor == 0 {
break
}
} }
return keys, nil return keys, nil
} }
@@ -261,6 +253,83 @@ func GetHash(source, key string) (map[string]string, error) {
return value, nil return value, nil
} }
// 批量获得缓存数据 [key]result
func GetHashBatch(source string, keys []string) (map[string]map[string]string, error) {
result := make(map[string]map[string]string, 0)
if len(keys) == 0 {
return result, fmt.Errorf("not keys")
}
// 数据源
rdb := DefaultRDB()
if source != "" {
rdb = RDB(source)
}
ctx := context.Background()
// 创建一个有限的并发控制信号通道
sem := make(chan struct{}, 10)
var wg sync.WaitGroup
var mt sync.Mutex
batchSize := 1000
total := len(keys)
if total < batchSize {
batchSize = total
}
for i := 0; i < total; i += batchSize {
wg.Add(1)
go func(start int) {
// 并发控制,限制同时执行的 Goroutine 数量
sem <- struct{}{}
defer func() {
wg.Done()
<-sem
}()
pipe := rdb.Pipeline()
for _, key := range keys[start : start+batchSize] {
pipe.HGetAll(ctx, key)
}
cmds, err := pipe.Exec(ctx)
if err != nil {
logger.Errorf("Failed to get hash batch exec err: %v", err)
return
}
// 将结果添加到 result map 并发访问
mt.Lock()
defer mt.Unlock()
// 处理命令结果
for _, cmd := range cmds {
if cmd.Err() != nil {
logger.Errorf("Failed to get hash batch cmds err: %v", cmd.Err())
continue
}
// 将结果转换为 *redis.StringStringMapCmd 类型
rcmd, ok := cmd.(*redis.MapStringStringCmd)
if !ok {
logger.Errorf("Failed to get hash batch type err: %v", cmd.Err())
continue
}
key := "-"
args := rcmd.Args()
if len(args) > 0 {
key = fmt.Sprint(args[1])
}
result[key] = rcmd.Val()
}
}(i)
}
wg.Wait()
return result, nil
}
// 判断是否存在 // 判断是否存在
func Has(source string, keys ...string) (bool, error) { func Has(source string, keys ...string) (bool, error) {
// 数据源 // 数据源

View File

@@ -43,14 +43,18 @@ func (r *UDMAuthUser) dataByRedis(imsi, neId string) []model.UDMAuthUser {
if err != nil { if err != nil {
return arr return arr
} }
for _, key := range ausfArr { mkv, err := redis.GetHashBatch(source, ausfArr)
m, err := redis.GetHash(source, key) if err != nil {
if err != nil { return arr
}
for k, m := range mkv {
if k == "-" {
continue continue
} }
// 跳过-号数据 ausf:360000100000130 // 跳过-号数据 ausf:360000100000130
imsi := key[5:] imsi := k[5:]
if strings.Contains(imsi, "-") { if strings.Contains(imsi, "-") {
continue continue
} }

View File

@@ -44,14 +44,24 @@ func (r *UDMSubUser) dataByRedis(imsi, neId string) []model.UDMSubUser {
if err != nil { if err != nil {
return arr return arr
} }
for _, key := range udmsdArr { mkv, err := redis.GetHashBatch(source, udmsdArr)
m, err := redis.GetHash(source, key) if err != nil {
if err != nil { return arr
}
for k, m := range mkv {
if k == "-" {
continue
}
// 跳过-号数据 udm-sd:360000100000130
imsi := k[7:]
if strings.Contains(imsi, "-") {
continue continue
} }
a := model.UDMSubUser{ a := model.UDMSubUser{
IMSI: key[7:], // udm-sd:360000100000130 IMSI: imsi, // udm-sd:360000100000130
MSISDN: m["gpsi"], // 8612300000130 MSISDN: m["gpsi"], // 8612300000130
NeId: neId, NeId: neId,
SmfSel: m["smf-sel"], // def_snssai SmfSel: m["smf-sel"], // def_snssai