golang redisの使用(二)

3319 ワード

redis接続プール接続プールは,以前に確立した接続を多重化することを目的とし,毎回TCP接続を再構築することなくスループットを向上させる.MaxIdle:poolで最大Idle接続数MaxActive:poolで最大に割り当てられた接続数をいくつかのパラメータで説明します.IdleTimeout:idleの時間を0に設定し、idleの時間を超えて接続を閉じます.0 idleに設定した接続はcloseWaitではありません:trueに設定し、要求時にMaxActiveに達すると接続がcloseされるのを待つことになります.falseに設定すると、要求時にMaxActiveに達するとerrorが返されます.
package main

import (
    "fmt"
    "os"
    "sync"
    "time"

    redis "github.com/gomodule/redigo/redis"
)

const (
    MAXIDLE       = 50
    MAXACTIVE     = 5000
    IDLETIMEOUT   = 30 * time.Second
    ROUNTINECOUNT = 50
)

func deferClose(con *redis.Conn) {
    fmt.Println("close")
    (*con).Close()
}

func main() {

    redisPool := &redis.Pool{
        MaxIdle:     MAXIDLE,
        MaxActive:   MAXACTIVE,
        IdleTimeout: IDLETIMEOUT,
        Wait:        true,
        Dial: func() (redis.Conn, error) {
            c, err := redis.Dial("tcp",
                "172.17.84.205:6379",
                redis.DialKeepAlive(20*time.Second),
                redis.DialPassword("123456"),
                redis.DialConnectTimeout(15*time.Second),
                redis.DialReadTimeout(15*time.Second),
                redis.DialWriteTimeout(15*time.Second))

            if err != nil {
                fmt.Println(err)
            }
            return c, err
        },
    }

    var wg sync.WaitGroup
    wg.Add(2 * ROUNTINECOUNT)

    for i := 0; i < ROUNTINECOUNT; i++ {
        go func(routineNum int) {
            for cnt := 0; cnt < 1000; cnt++ {
                c := redisPool.Get()
                //defer c.Close()

                key := fmt.Sprintf("key_%d_%d", routineNum, cnt)
                value := fmt.Sprintf("value_%d_%d", routineNum, cnt)

                _, err := c.Do("set", key, value)
                if err != nil {
                    fmt.Printf("set %s:%v
", key, err) } fmt.Printf("s %s
", value) if cnt%50 == 0 { aCount := redisPool.Stats().ActiveCount wCount := redisPool.Stats().WaitCount fmt.Printf("activeCount:%d, waitCount:%d
", aCount, wCount) } c.Close() //time.Sleep(50 * time.Millisecond) } wg.Done() }(i) go func(routineNum int) { for cnt := 0; cnt < 1000; cnt++ { c := redisPool.Get() //defer c.Close() key := fmt.Sprintf("key_%d_%d", routineNum, cnt) value, err := redis.String(c.Do("get", key)) if err != nil { fmt.Printf("get %s:%v
", key, err) } fmt.Printf("g %s
", value) c.Close() } wg.Done() }(i) } wg.Wait() } func errCheck(err error) { if err != nil { fmt.Println(err) os.Exit(-1) } }

テスト時に検出
c := redisPool.Get()
defer c.Close()

Close()は常に実行されていないので、MaxActiveに達すると引っかかり、実行されません.使用済みで直接c.Close()を呼び出す原因はよく調べていませんが、誰か原因がわかったら教えてください
詳細コード:https://github.com/BinWang-sh...