This commit is contained in:
2025-07-28 01:46:39 +08:00
parent b03129667a
commit 357639462a
219 changed files with 21634 additions and 8138 deletions

View File

@@ -4,6 +4,7 @@ import (
"context"
"encoding/json"
"fmt"
"strings"
"time"
"github.com/redis/go-redis/v9"
@@ -85,6 +86,7 @@ func (r *RedisCache) Set(ctx context.Context, key string, value interface{}, ttl
data, err := json.Marshal(value)
if err != nil {
r.logger.Error("序列化缓存数据失败", zap.String("key", key), zap.Error(err))
return fmt.Errorf("failed to marshal value: %w", err)
}
@@ -106,10 +108,11 @@ func (r *RedisCache) Set(ctx context.Context, key string, value interface{}, ttl
err = r.client.Set(ctx, fullKey, data, expiration).Err()
if err != nil {
r.logger.Error("Failed to set cache", zap.String("key", key), zap.Error(err))
r.logger.Error("设置缓存失败", zap.String("key", key), zap.Error(err))
return err
}
r.logger.Debug("设置缓存成功", zap.String("key", key), zap.Duration("ttl", expiration))
return nil
}
@@ -158,6 +161,7 @@ func (r *RedisCache) GetMultiple(ctx context.Context, keys []string) (map[string
values, err := r.client.MGet(ctx, fullKeys...).Result()
if err != nil {
r.logger.Error("批量获取缓存失败", zap.Strings("keys", keys), zap.Error(err))
return nil, err
}
@@ -165,9 +169,15 @@ func (r *RedisCache) GetMultiple(ctx context.Context, keys []string) (map[string
for i, val := range values {
if val != nil {
var data interface{}
if err := json.Unmarshal([]byte(val.(string)), &data); err == nil {
result[keys[i]] = data
// 修复改进JSON反序列化错误处理
if err := json.Unmarshal([]byte(val.(string)), &data); err != nil {
r.logger.Warn("反序列化缓存数据失败",
zap.String("key", keys[i]),
zap.String("value", val.(string)),
zap.Error(err))
continue
}
result[keys[i]] = data
}
}
@@ -210,17 +220,107 @@ func (r *RedisCache) SetMultiple(ctx context.Context, data map[string]interface{
// DeletePattern 按模式删除
func (r *RedisCache) DeletePattern(ctx context.Context, pattern string) error {
fullPattern := r.getFullKey(pattern)
keys, err := r.client.Keys(ctx, fullPattern).Result()
if err != nil {
return err
// 修复:避免重复添加前缀
var fullPattern string
if strings.HasPrefix(pattern, r.prefix+":") {
fullPattern = pattern
} else {
fullPattern = r.getFullKey(pattern)
}
if len(keys) > 0 {
return r.client.Del(ctx, keys...).Err()
// 检查上下文是否已取消
if ctx.Err() != nil {
return ctx.Err()
}
var cursor uint64
var totalDeleted int64
maxIterations := 100 // 防止无限循环
iteration := 0
for {
// 检查迭代次数限制
iteration++
if iteration > maxIterations {
r.logger.Warn("缓存删除操作达到最大迭代次数限制",
zap.String("pattern", fullPattern),
zap.Int("max_iterations", maxIterations),
zap.Int64("total_deleted", totalDeleted),
)
break
}
// 检查上下文是否已取消
if ctx.Err() != nil {
r.logger.Warn("缓存删除操作被取消",
zap.String("pattern", fullPattern),
zap.Int64("total_deleted", totalDeleted),
zap.Error(ctx.Err()),
)
return ctx.Err()
}
// 执行SCAN操作
keys, next, err := r.client.Scan(ctx, cursor, fullPattern, 1000).Result()
if err != nil {
// 如果是上下文取消错误,直接返回
if err == context.Canceled || err == context.DeadlineExceeded {
r.logger.Warn("缓存删除操作被取消",
zap.String("pattern", fullPattern),
zap.Int64("total_deleted", totalDeleted),
zap.Error(err),
)
return err
}
r.logger.Error("扫描缓存键失败",
zap.String("pattern", fullPattern),
zap.Error(err))
return err
}
// 批量删除找到的键
if len(keys) > 0 {
// 使用pipeline批量删除提高性能
pipe := r.client.Pipeline()
pipe.Del(ctx, keys...)
cmds, err := pipe.Exec(ctx)
if err != nil {
r.logger.Error("批量删除缓存键失败",
zap.Strings("keys", keys),
zap.Error(err))
return err
}
// 统计删除的键数量
for _, cmd := range cmds {
if delCmd, ok := cmd.(*redis.IntCmd); ok {
if deleted, err := delCmd.Result(); err == nil {
totalDeleted += deleted
}
}
}
r.logger.Debug("批量删除缓存键",
zap.Strings("keys", keys),
zap.Int("batch_size", len(keys)),
zap.Int64("total_deleted", totalDeleted),
)
}
cursor = next
if cursor == 0 {
break
}
}
r.logger.Debug("缓存模式删除完成",
zap.String("pattern", fullPattern),
zap.Int64("total_deleted", totalDeleted),
zap.Int("iterations", iteration),
)
return nil
}