当使用 rdb.Pipelined
时,我在 Go 中遇到 github.com/go-redis/redis/v9
包的问题。我有一个包含两个 Get 查询的管道,一个数据存在,而第二个不存在。但我仍然收到 redis: nil
错误。
这是示例代码:
ctx := context.Background() _, err := rdb.Pipelined(ctx, func(pipe redis.Pipeliner) error { pipe.Get(ctx, "key1") pipe.Get(ctx, "key2") return nil }) if err != nil { log.Printf("Error executing pipeline: %v", err) }
“key1”存在于 redis 中,“key2”则不存在。我可以使用 Redis CLI 来验证这一点。当我执行 rdb.Get(ctx, "key1").Result()
时,它也会返回数据。
同样的事情在 EC2 的临时环境中运行良好。
我已经检查了拼写错误并确保密钥存在。造成这种差异的原因是什么?如何解决?
其他信息: Redis服务器版本:7.0.11 Go-Redis版本:v9.1.0 Go版本:go1.21.0 darwin/arm64 操作系统:MacOs
感谢您提供有关如何排查和解决此问题的见解或建议。
我们可以在go-redis
源代码中找到这个:
// Exec executes all previously queued commands using one
// client-server roundtrip.
//
// Exec always returns list of commands and error of the first failed
// command if any.
func (c *Pipeline) Exec(ctx context.Context) ([]Cmder, error) {
if len(c.cmds) == 0 {
return nil, nil
}
cmds := c.cmds
c.cmds = nil
return cmds, c.exec(ctx, cmds)
}
func (c *Pipeline) Pipelined(ctx context.Context, fn func(Pipeliner) error) ([]Cmder, error) {
if err := fn(c); err != nil {
return nil, err
}
return c.Exec(ctx)
}
所以也许你可以这样使用它:
var results []string cmds, _ := cli.Pipelined(context.TODO(), func(pipeliner redis.Pipeliner) error { return nil }) for _, cmd := range cmds { if cmd.Err() != nil && cmd.Err() != redis.Nil { // log error continue } res := cmd.(*redis.StringCmd).Val() results = append(results, res) }