redigo连接池 – 为什么在删除过期连接时释放锁定

huangapple go评论76阅读模式
英文:

redigo connection pool - Why release lock when removing stale connection

问题

Redigo是用于Redis数据库的Golang客户端。它使用结构体Pool来维护连接池。这个结构体持有一个互斥锁,用于应用程序并行地放置和获取连接。

在它的get方法中,连接池首先移除过期的(空闲超时)连接。当找到一个过期的连接时,连接池会弹出它,释放锁,然后关闭连接,并尝试重新获取锁。

为什么连接池在解锁后又尝试重新获取锁,而不是在函数返回之前解锁呢?我猜关闭一个连接可能需要相当长的时间,这会减慢其他等待该互斥锁的goroutine的速度。

这是整个Pool get方法

英文:

Redigo is a golang client for the redis database. It uses struct Pool to maintain a pool of connections. This struct holds a mutex lock for application putting and getting connection parallelly.

type Pool struct {
    // ...
    IdleTimeout time.Duration
	mu     sync.Mutex
    // Stack of idleConn with most recently used at the front.
    idle list.List
}

In its get method, connection pool removes stale (idle timeout) connections firstly. When finding a stale connection, the pool pops it, releases lock, then closes connection, tries to acquire lock again.

func (p *Pool) get() (Conn, error) {
    p.mu.Lock()

    // Prune stale connections.

    if timeout := p.IdleTimeout; timeout > 0 {
	    for i, n := 0, p.idle.Len(); i < n; i++ {
		    e := p.idle.Back()
		    if e == nil {
			    break
		    }
		    ic := e.Value.(idleConn)
 			    if ic.t.Add(timeout).After(nowFunc()) {
    				break
	        	}
			p.idle.Remove(e)
    		p.release()
            // Why does pool unlock and try to acquire lock again?
		    p.mu.Unlock()
            // Close this stale connection.
		    ic.c.Close()
		    p.mu.Lock()
	    }
    }

Why does pool unlock and try to acquire lock again, instead of just unlocking before function returns? I guess closing a connection may cost quite a lot time, which will slow down other goroutine waiting on this mutex.

Here is the whole Pool get method

答案1

得分: 0

关闭连接可能需要很长时间,这会减慢其他等待该互斥锁的goroutine的速度。正如@Cerise Limón所说,锁定整个池的使用时间似乎是不明智的。

在解锁互斥锁之后,等待的goroutine之一会获取到互斥锁。虽然get方法的goroutine仍然需要删除过期的连接,但put方法的goroutine可以将连接放回池中,并尽快继续其他工作。

英文:

Close a connection may cost quite a lot time, which will slow down other goroutine waiting on this mutex. As what @Cerise Limón said - It seems unwise to lock all use of the pool for this time.

After unlocking the mutex, one of the waiting goroutines gets the mutex. Although goroutine for get method still needs to remove stale connections, the one for put method can put connection to pool and continue to do other work as soon as possible.

huangapple
  • 本文由 发表于 2017年3月13日 08:16:17
  • 转载请务必保留本文链接:https://go.coder-hub.com/42754823.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定