Skip to content

connCheck may have a great impact on performance #2599

@ljun20160606

Description

@ljun20160606

Checking the connection whenever we get a connection from the connection pool can have a great impact on performance.

func (p *ConnPool) isHealthyConn(cn *Conn) bool {
now := time.Now()
if p.cfg.ConnMaxLifetime > 0 && now.Sub(cn.createdAt) >= p.cfg.ConnMaxLifetime {
return false
}
if p.cfg.ConnMaxIdleTime > 0 && now.Sub(cn.UsedAt()) >= p.cfg.ConnMaxIdleTime {
return false
}
if connCheck(cn.netConn) != nil {
return false
}
cn.SetUsedAt(now)
return true
}

I recently did a test where I wrote a simple proxy and used go-redis as the proxy client. I ran redis-benchmark -n 100000 on my Mac and took a pprof profile at the same time. I found that it took around 10% of the cost.

What do you think to add an option like TestOnBorrow? The code would look like as follows.

var TestOnBorrow func(c net.Conn, t time.Time) error

func (p *ConnPool) isHealthyConn(cn *Conn) bool {
	now := time.Now()

	if p.cfg.ConnMaxLifetime > 0 && now.Sub(cn.createdAt) >= p.cfg.ConnMaxLifetime {
		return false
	}
	if p.cfg.ConnMaxIdleTime > 0 && now.Sub(cn.UsedAt()) >= p.cfg.ConnMaxIdleTime {
		return false
	}

	if p.cfg.TestOnBorrow == nil {
		if connCheck(cn.netConn) != nil {
			return false
		}
	} else {
		if err := p.cfg.TestOnBorrow(cn.netConn, cn.UsedAt()); err != nil {
			return false
		}
	}

	cn.SetUsedAt(now)
	return true
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions