Home  >  Article  >  Backend Development  >  Redis: "redis: nil" error in rdb.Pipelined although data exists

Redis: "redis: nil" error in rdb.Pipelined although data exists

PHPz
PHPzforward
2024-02-09 11:50:09432browse

Redis:尽管数据存在,但 rdb.Pipelined 中出现“redis:nil”错误

php Editor Banana may encounter a problem when using Redis: although the data exists, a "redis:nil" error appears in rdb.Pipelined. This error may cause the data to not be read correctly, causing trouble to the program. Before solving this problem, we first need to understand its causes and possible solutions. In this article, I will analyze this problem in detail for you and provide some practical solutions to help you solve this error smoothly.

Question content

I encountered github.com/go-redis/redis/v9 when using rdb.Pipelined Package problem. I have a pipeline with two Get queries, one the data exists and the second one doesn't. But I still get redis: nil error.

This is the sample code:

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" exists in redis, but "key2" does not exist. I can verify this using the Redis CLI. When I do rdb.Get(ctx, "key1").Result() it also returns the data. The same thing works fine in a staging environment on EC2.

I've checked for typos and made sure the key exists. What is the reason for this difference? How to solve?

other information: Redis server version: 7.0.11 Go-Redis version: v9.1.0 Go version: go1.21.0 darwin/arm64 Operating system: MacOs

Thanks for any insights or suggestions on how to troubleshoot and resolve this issue.

Solution

We can find this in the go-redis source code:

<code>// 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)
}
</code>

So maybe you can use it like this:

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)
}

The above is the detailed content of Redis: "redis: nil" error in rdb.Pipelined although data exists. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:stackoverflow.com. If there is any infringement, please contact admin@php.cn delete