英文:
Re-using Redigo connection instead of recreating it every time
问题
连接到Redigo并在函数内部操作数据就像涂抹黄油一样容易,但当你需要重复使用连接时,问题就来了,显然是出于性能/实用性的原因。
像这样在函数内部操作是可以的:
func main() {
    client, err := redis.Dial("tcp", ":6379")
    if err != nil {
        panic(err)
    }
    defer client.Close()
    client.Do("GET", "test:1")
}
但是将其放在外部就不行:
var Client = redis.Dial("tcp", ":6379")
defer Client.Close()
func main() {
    Client.Do("GET", "test:1")
}
会返回以下错误:
./main.go:1: multiple-value redis.Dial() in single-value context
./main.go:2: non-declaration statement outside function body
我尝试将连接放在const(常量)中,将defer放在主函数中,但都没有奏效。
这是一个更大的问题,因为我有许多其他函数需要与Redis通信,但每次重新创建Redis连接似乎很愚蠢。
Redigo API只展示了如何创建一个Dial实例,但没有进一步解释如何重复使用它。
也许你在我的讲话中迷失了,但我想在这里提供一些背景信息,所以我的明确而简明的问题是:你如何重复使用(而不是每次重新创建)Redigo连接?
英文:
Connecting to Redigo and manipulating data inside a function is easy like butter, but the problem comes when you have to re-use its connection, obviously for performance/practicality reasons.
Doing it inside a function like this works:
func main() {
    client, err := redis.Dial("tcp", ":6379")
    if err != nil {
        panic(err)
    }
    defer client.Close()
    client.Do("GET", "test:1")
}
But bringing it outside doesn't:
var Client = redis.Dial("tcp", ":6379")
defer Client.Close()
func main() {
    
        Client.Do("GET", "test:1")
    }
With the following error(s) returned:
./main.go:1: multiple-value redis.Dial() in single-value context
./main.go:2: non-declaration statement outside function body
I've tried putting the connection as a const(ant), putting defer inside the main function to my dismay not working too.
This is an even bigger concern as I have many other functions that have to communicate to Redis, but recreating the connection to Redis everytime seems silly.
The Redigo API just shows how to create a Dial instance but doesn't go further by explaining how to re-use it.
You may've been lost in my talk, but I wanted to put a bit of context here, so my clear and concise question is: How do you go about re-using (not recreating everytime) a Redigo connection?
答案1
得分: 21
最好的方法是使用Pools,这里简要介绍了它的用法:Redigo Pools。
全局变量最终不会重用连接,所以我最终使用了类似下面的代码(使用了之前提到的Pools):
func newPool() *redis.Pool {
    return &redis.Pool{
        MaxIdle:   80,
        MaxActive: 12000, // 最大连接数
        Dial: func() (redis.Conn, error) {
            c, err := redis.Dial("tcp", ":6379")
            if err != nil {
                panic(err.Error())
            }
            return c, err
        },
    }
}
var pool = newPool()
func main() {
    c := pool.Get()
    defer c.Close()
    test, _ := c.Do("HGETALL", "test:1")
    fmt.Println(test)
}
如果你想在另一个函数中重用这个连接池,可以这样做:
```go
func test() {
    c := pool.Get()
    defer c.Close()
    test2, _ := c.Do("HGETALL", "test:2")
    fmt.Println(test2)
}
英文:
The best way turned out to be using Pools, which are briefly documented here: Redigo Pools.
A global variable won't eventually reuse a connection, so I ended up with something like this (using Pools as noted before):
func newPool() *redis.Pool {
return &redis.Pool{
            MaxIdle: 80,
            MaxActive: 12000, // max number of connections
            Dial: func() (redis.Conn, error) {
                    c, err := redis.Dial("tcp", ":6379")
                    if err != nil {
                            panic(err.Error())
                    }
                    return c, err
            },
    } 
    
}
var pool = newPool()
func main() {
  
        c := pool.Get()
        defer c.Close()
  
        test,_:=c.Do("HGETALL", "test:1")
        fmt.Println(test)
}
If for example you want to reuse a pool inside another function you do it like this:
func test() {
        c := pool.Get()
        defer c.Close()
        
        test2,_:=c.Do("HGETALL", "test:2")
        fmt.Println(test2)
}
答案2
得分: -1
redis.Dial()方法返回客户端错误。要修复它,你应该将以下代码替换为:
var Client, _ = redis.Dial("tcp", ":6379")
英文:
The redis.Dial() method returns client error. To fix it, you should replace:
var Client = redis.Dial("tcp", ":6379") 
with:
var Client, _ = redis.Dial("tcp", ":6379")
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论