6

使用 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 时都必须选择 db 似乎是多余的,而且还会带来一个问题,因为我将它用于会话,即使用不是我的代码与我的池中的 redis 连接一起工作,这使得“不可能”设置正确的 db它。

我想做的是为池设置dbno,这样每当有人要求从池中建立新连接时,它就会带有已经设置的正确db,即每次都没有明确设置它。

你是如何在你的应用程序中解决这个问题的?

谢谢。

4

4 回答 4

9

您可以使用redis.DialOption: redis.DialDatabase,redis.DialPassword

conn, err := redis.Dial("tcp", "127.0.0.1:6379", redis.DialDatabase(1))
if err != nil {
    panic(err)
}
defer conn.Close()
于 2017-06-07T08:49:41.200 回答
5

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

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

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

于 2014-09-07T20:05:58.680 回答
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()
    
于 2014-09-07T08:54:29.450 回答
0

最好的方法是使用DialOptions like 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
    },
}
于 2017-08-25T14:44:28.833 回答