Golang:在Redigo的RedisPool上选择DB

时间:2014-09-07 08:09:21

标签: go redis redigo

使用redigo,我创建了一个像这样的游泳池:

&redis.Pool{
    MaxIdle:   80,
    MaxActive: 12000, // max number of connections
    Dial: func() (redis.Conn, error) {
        c, err := redis.Dial("tcp", host+":"+port)
        if err != nil {
            panic(err.Error())
        }
        return c, err
    }

我遇到的问题是每次我得到一个新的连接时,我需要设置数据库,因为我使用不同的数据库的redis,因为我在VPS上托管了很多站点。

所以,像这样:

conn := pool.Get()
defer conn.Close()

conn.Do("SELECT", dbNumber)  //this is the call I want to avoid

每次使用redis时都必须选择数据库似乎是多余的,并且因为我将它用于会话时也会出现问题,即使用我的池中的redis连接不能使用的代码使得“无法”设置正确的数据库。

我想要做的是为池设置dbno,以便每当有人从池中请求新连接时,它都会附带正确的数据库,即每次都没有明确设置它。

您是如何在应用程序中解决此问题的?

感谢。

4 个答案:

答案 0 :(得分:4)

在拨号功能中选择数据库:

&redis.Pool{
    MaxIdle:   80,
    MaxActive: 12000, // max number of connections
    Dial: func() (redis.Conn, error) {
        c, err := redis.Dial("tcp", host+":"+port)
        if err != nil {
            return nil, err
        }
        _, err := c.Do("SELECT", dbNum)
        if err != nil {
           c.Close()
           return nil, err
        }
        return c, nil
    }

此外,从拨号返回错误而不是恐慌。

答案 1 :(得分:3)

您可以使用redis.DialOptionredis.DialDatabaseredis.DialPassword

conn, err := redis.Dial("tcp", "127.0.0.1:6379", redis.DialDatabase(1))
if err != nil {
    panic(err)
}
defer conn.Close()

答案 2 :(得分:2)

如果这些图书馆不支持,那么您有两种选择:

  1. 提交补丁以自动执行此操作(python lib执行此操作,但在保持状态时要小心)。

  2. 使用您自己的自定义池自定义您的redis池,例如(未经测试的代码,但您会得到这个想法):

        // a pool embedding the original pool and adding adbno state
        type DbnoPool struct {
           redis.Pool
           dbno int
        }
    
    
        // "overriding" the Get method
        func (p *DbnoPool)Get() Connection {
           conn := p.Pool.Get()
           conn.Do("SELECT", p.dbno)
           return conn
        }
    
        pool := &DbnoPool {
            redis.Pool{
                MaxIdle:   80,
                MaxActive: 12000, // max number of connections
                Dial: func() (redis.Conn, error) {
                c, err := redis.Dial("tcp", host+":"+port)
                if err != nil {
                    panic(err.Error())
                }
                return c, err
            },
            3, // the db number
        }
    
        //now you call it normally
        conn := pool.Get()
        defer conn.Close()
    

答案 3 :(得分:0)

最好的方法是使用DialOption之类的DialDatabase

redisPool = &redis.Pool{

    MaxIdle:     AppConfig.DefaultInt("RedisMaxPool", 10),
    IdleTimeout: 240 * time.Second,

    Dial: func() (redis.Conn, error) {
        c, err := redis.Dial(
            "tcp",
            AppConfig.DefaultString("RedisPath", ":6379"),
            redis.DialDatabase(AppConfig.DefaultInt("RedisDB", 1)),
        )
        if err != nil {
            return nil, err
        }
        return c, err
    },

    TestOnBorrow: func(c redis.Conn, t time.Time) error {
        _, err := c.Do("PING")
        return err
    },
}