package redis import ( "context" "errors" "fmt" "time" "carrotskin/pkg/config" "github.com/redis/go-redis/v9" "go.uber.org/zap" ) // Client Redis客户端包装 type Client struct { *redis.Client logger *zap.Logger } // New 创建Redis客户端 func New(cfg config.RedisConfig, logger *zap.Logger) (*Client, error) { // 创建Redis客户端 rdb := redis.NewClient(&redis.Options{ Addr: fmt.Sprintf("%s:%d", cfg.Host, cfg.Port), Password: cfg.Password, DB: cfg.Database, PoolSize: cfg.PoolSize, DialTimeout: 5 * time.Second, ReadTimeout: 3 * time.Second, WriteTimeout: 3 * time.Second, }) // 测试连接 ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() if err := rdb.Ping(ctx).Err(); err != nil { return nil, fmt.Errorf("Redis连接失败: %w", err) } logger.Info("Redis连接成功", zap.String("host", cfg.Host), zap.Int("port", cfg.Port), zap.Int("database", cfg.Database), ) return &Client{ Client: rdb, logger: logger, }, nil } // Close 关闭Redis连接 func (c *Client) Close() error { c.logger.Info("正在关闭Redis连接") return c.Client.Close() } // Set 设置键值对(带过期时间) func (c *Client) Set(ctx context.Context, key string, value interface{}, expiration time.Duration) error { return c.Client.Set(ctx, key, value, expiration).Err() } // Get 获取键值 func (c *Client) Get(ctx context.Context, key string) (string, error) { return c.Client.Get(ctx, key).Result() } // Del 删除键 func (c *Client) Del(ctx context.Context, keys ...string) error { return c.Client.Del(ctx, keys...).Err() } // Exists 检查键是否存在 func (c *Client) Exists(ctx context.Context, keys ...string) (int64, error) { return c.Client.Exists(ctx, keys...).Result() } // Expire 设置键的过期时间 func (c *Client) Expire(ctx context.Context, key string, expiration time.Duration) error { return c.Client.Expire(ctx, key, expiration).Err() } // Incr 自增 func (c *Client) Incr(ctx context.Context, key string) (int64, error) { return c.Client.Incr(ctx, key).Result() } // Decr 自减 func (c *Client) Decr(ctx context.Context, key string) (int64, error) { return c.Client.Decr(ctx, key).Result() } // HSet 设置哈希字段 func (c *Client) HSet(ctx context.Context, key string, values ...interface{}) error { return c.Client.HSet(ctx, key, values...).Err() } // HGet 获取哈希字段 func (c *Client) HGet(ctx context.Context, key, field string) (string, error) { return c.Client.HGet(ctx, key, field).Result() } // HGetAll 获取所有哈希字段 func (c *Client) HGetAll(ctx context.Context, key string) (map[string]string, error) { return c.Client.HGetAll(ctx, key).Result() } // HDel 删除哈希字段 func (c *Client) HDel(ctx context.Context, key string, fields ...string) error { return c.Client.HDel(ctx, key, fields...).Err() } // SAdd 添加集合成员 func (c *Client) SAdd(ctx context.Context, key string, members ...interface{}) error { return c.Client.SAdd(ctx, key, members...).Err() } // SMembers 获取集合所有成员 func (c *Client) SMembers(ctx context.Context, key string) ([]string, error) { return c.Client.SMembers(ctx, key).Result() } // SRem 删除集合成员 func (c *Client) SRem(ctx context.Context, key string, members ...interface{}) error { return c.Client.SRem(ctx, key, members...).Err() } // SIsMember 检查是否是集合成员 func (c *Client) SIsMember(ctx context.Context, key string, member interface{}) (bool, error) { return c.Client.SIsMember(ctx, key, member).Result() } // ZAdd 添加有序集合成员 func (c *Client) ZAdd(ctx context.Context, key string, members ...redis.Z) error { return c.Client.ZAdd(ctx, key, members...).Err() } // ZRange 获取有序集合范围内的成员 func (c *Client) ZRange(ctx context.Context, key string, start, stop int64) ([]string, error) { return c.Client.ZRange(ctx, key, start, stop).Result() } // ZRem 删除有序集合成员 func (c *Client) ZRem(ctx context.Context, key string, members ...interface{}) error { return c.Client.ZRem(ctx, key, members...).Err() } // Pipeline 创建管道 func (c *Client) Pipeline() redis.Pipeliner { return c.Client.Pipeline() } // TxPipeline 创建事务管道 func (c *Client) TxPipeline() redis.Pipeliner { return c.Client.TxPipeline() } func (c *Client) Nil(err error) bool { return errors.Is(err, redis.Nil) } // GetBytes 从Redis读取key对应的字节数据,统一处理错误 func (c *Client) GetBytes(ctx context.Context, key string) ([]byte, error) { val, err := c.Client.Get(ctx, key).Bytes() if err != nil { if errors.Is(err, redis.Nil) { // 处理key不存在的情况(返回nil,无错误) return nil, nil } return nil, err // 其他错误(如连接失败) } return val, nil }