gomodule redigo产生大量time_wait,是配置有问题吗?

作者站长头像
站长
· 阅读数 10

大牛们好,最近我使用go写一个服务用到了gomodule/redigo 这个组件 (https://github.com/gomodule/r...) ,我的服务访问量较大, qps大概是3000~6000,然后服务端出现了大量的time_wait,全是服务端与redis之间的。我的redis连接池配置是这样的:

/**
 * until redigo supports sharding/clustering, only one host will be in hostList
 * @Description:实例化一个redis
 * @param host
 * @param password
 * @param defaultExpiration
 * @return *redis.Pool
 */
func newRedisStore(host string, password string, defaultExpiration time.Duration) *RedisStore {
    //host = "192.168.0.16:6379"
    var pool = &redis.Pool{
        MaxIdle:16,            //最初的连接数量
        MaxActive:512,        //连接池最大连接数量,不确定可以用0(0表示自动定义),按需分配
        Wait: false,
        IdleTimeout: 60 * time.Second,    //连接关闭时间 300秒 (300秒不使用自动关闭)
        Dial: func() (redis.Conn, error) {
            // the redis protocol should probably be made sett-able
            c, err := redis.Dial("tcp", host)
            if err != nil {
                return nil, err
            }
            if len(password) > 0 {
                if _, err := c.Do("AUTH", password); err != nil {
                    c.Close()
                    return nil, err
                }
            } else {
                // check with PING
                if _, err := c.Do("PING"); err != nil {
                    c.Close()
                    return nil, err
                }
            }
            return c, err
        },
        // custom connection test method
        TestOnBorrow: func(c redis.Conn, t time.Time) error {
            if _, err := c.Do("PING"); err != nil {
                return err
            }
            return nil
        },
    }
    return &RedisStore{pool: pool, defaultExpiration: defaultExpiration}
}

应用层调用redis方法是类似这样的:

/**
 * @Description: 获取一个key值
 * @receiver c
 * @param key
 * @param ptrValue 指针
 * @return error
 */
func (c *RedisStore) Get(key string, ptrValue interface{}) error {
    conn := c.pool.Get()
    defer conn.Close()
    
    reply, err := conn.Do("GET", key)
    if reply != nil {
        item, err := redis.Bytes(reply, err)
        if err != nil {
            return err
        }
        return deserialize(item, ptrValue)
    }
    return nil
}

在访问高峰,自己服务与redis之间的time_witee 3000个左右 ,这明显是有问题的。但是我现在还不确定哪里有问题。上面的写法都是官方写法。我推测 ,用了连接池,那么每次用完后,不能close,close掉了不就是频繁连接,关闭了吗,这样time_wait就出现了。

官方文档里有写明:从pool里取出一个连接用完后要关闭。

https://pkg.go.dev/github.com...

gomodule  redigo产生大量time_wait,是配置有问题吗?

实在不知怎么弄了。大牛们使用redis是怎么避免这个情况的?

回复
1个回答
avatar
test
2024-07-14

这么久了没人回答。。是redis配置不合理了,导致 频繁建立和销毁连接

回复
likes
适合作为回答的
  • 经过验证的有效解决办法
  • 自己的经验指引,对解决问题有帮助
  • 遵循 Markdown 语法排版,代码语义正确
不该作为回答的
  • 询问内容细节或回复楼层
  • 与题目无关的内容
  • “赞”“顶”“同问”“看手册”“解决了没”等毫无意义的内容