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

大牛们好,最近我使用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...

image.png

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

阅读 2.1k
1 个回答

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

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进