redigoのredis.Pool構成パラメータのチューニング
9116 ワード
reids.Pool構造の紹介
接続プールからの接続の取得
接続を閉じる
シーンの設定
主なパラメータを見てみましょう MaxIdle は、接続プールの空き接続リストの長さ制限 を示す.空きリストは桟式の構造で、先進的に を出た.
MaxActive 接続プールの中で最も大きい接続数の制限 を表すは、サービス側がサポートする接続数の上限と、アプリケーション間の「分割」接続数 を主に考慮する.
IdleTimeout アイドル接続のタイムアウト設定は、タイムアウトするとアイドルリストから が削除される.このタイムアウト時間は、サービス側の接続タイムアウト設定 よりも小さいべきである.
2つの使用シーンを区別します.高周波呼び出しのシーンは、redisのパフォーマンスをできるだけ搾取する必要があります. MaxIdleのサイズを大きくします.この数はmaxActiveより小さいです.バッファとして同じように存在するため、バッファを拡大しても問題はありません. MaxActiveを高くし、サービス側のサポート上限を考慮して、できるだけ を高くします. IdleTimeout高周波使用シーンなので、設定が短くても構いませんが、注意すべき点はMaxIdle設定が長くなり、キュー内の期限切れの接続が増える可能性があります.このときIdleTimeoutもそれに応じて 変化します.
低周波呼び出しのシーンは、呼び出し量がredisの負荷に達していないため、安定性が重要です. MaxIdleで設定できる小さな IdleTimeoutはそれに応じて小さい を設定する. MaxActive随意、足りればいい、異常を検出しやすい
// github.com/garyburd/redigo/redis/pool.go
type Pool struct {
// Dial() ,
Dial func() (Conn, error)
// TestOnBorrow() ,
TestOnBorrow func(c Conn, t time.Time) error
//
MaxIdle int
// pool
// 0 , pool
MaxActive int
// , 。
// 0,
// redis
IdleTimeout time.Duration
// Wait true, Get()
Wait bool
// mu protects fields defined below.
mu sync.Mutex
cond *sync.Cond
closed bool
active int
//
idle list.List
}
接続プールからの接続の取得
// get prunes stale connections and returns a connection from the idle list or
// creates a new connection.
func (p *Pool) get() (Conn, error) {
p.mu.Lock()
// idle
if timeout := p.IdleTimeout; timeout > 0 {
for i, n := 0, p.idle.Len(); i < n; i++ {
e := p.idle.Back()// idle ( )
if e == nil {
break
}
ic := e.Value.(idleConn)
if ic.t.Add(timeout).After(nowFunc()) { // ,
break
}
p.idle.Remove(e)//
p.release()// p.active,
p.mu.Unlock()
ic.c.Close()//
p.mu.Lock()
}
}
for {
// idle
for i, n := 0, p.idle.Len(); i < n; i++ {
e := p.idle.Front()// idle ,
if e == nil {
break
}
ic := e.Value.(idleConn)
p.idle.Remove(e)//
test := p.TestOnBorrow
p.mu.Unlock()
if test == nil || test(ic.c, ic.t) == nil {// ,
return ic.c, nil// ,
}
ic.c.Close()// ,
p.mu.Lock()
p.release()// p.active,
}
// pool
if p.closed {
p.mu.Unlock()
return nil, errors.New("redigo: get on closed pool")
}
//
if p.MaxActive == 0 || p.active < p.MaxActive {// active
dial := p.Dial
p.active += 1
p.mu.Unlock()
c, err := dial()// dial
if err != nil {
p.mu.Lock()
p.release()
p.mu.Unlock()
c = nil
}
return c, err
}
//
if !p.Wait {//
p.mu.Unlock()
return nil, ErrPoolExhausted
}
if p.cond == nil {
p.cond = sync.NewCond(&p.mu)
}
p.cond.Wait()// ,
}
}
接続を閉じる
func (p *Pool) put(c Conn, forceClose bool) error {
err := c.Err()
p.mu.Lock()
if !p.closed && err == nil && !forceClose {//p , ,
p.idle.PushFront(idleConn{t: nowFunc(), c: c})// idle
if p.idle.Len() > p.MaxIdle {// idle ( 1)
c = p.idle.Remove(p.idle.Back()).(idleConn).c// idle
} else {
c = nil
}
}
if c == nil {
if p.cond != nil {
p.cond.Signal()//
}
p.mu.Unlock()
return nil
}
p.release()// active
p.mu.Unlock()
return c.Close()//
}
シーンの設定
主なパラメータを見てみましょう
2つの使用シーンを区別します.