redigo接続プールはピットに入らない

3332 ワード

前に書く


goでwebプロジェクトを開発する際、redisをよく使いますが、redigoパッケージをお勧めします.現在4800以上のstarがあり、ほとんど大きな穴はありません.https://github.com/gomodule/redigo

redisのi/o同時について話します


Redis is single-threaded with epoll/kqueue and scales indefinitely in terms of I/O concurrency.
redisは単一スレッドですが、同時実行を実現しているのでしょうか.参照先:https://stackoverflow.com/questions/10489298/redis-is-single-threaded-then-how-does-it-do-concurrent-i-oredisイベントループを使用して同時実行を実現し、イベントは原子的であり、追加のロックオーバーヘッドはありません.デザインがとてもすばらしい.
我々はredisを読み書きする際,ほとんどがネットワーク伝送層のオーバーヘッドであり,redis計算は非常に速い.だから私たちはできるだけ複数の接続でredisを読み書きして、同時にネットの伝達をすることに相当して、列に並んでredis計算を待っていて、redis計算エンジンを暇にしてはいけません.

接続プールの使用


redigoを使うときは、接続プールを強くお勧めします.そうしないと、毎回tcpでチェーンを作らなければなりません.面倒ではありませんか.接続プールを使用すると,getに行くだけで他はクラスライブラリに渡して処理する.サンプルコードは次のとおりです.
var redisClient *redis.Poolfunc init() {
    maxIdle := MaxIdle    if v, ok := conf["MaxIdle"]; ok {
        maxIdle = int(v.(int64))
    }   
    maxActive := MaxActive    if v, ok := conf["MaxActive"]; ok {
        maxActive = int(v.(int64))
    }   

    //      
    redisClient = &redis.Pool{
        MaxIdle:     maxIdle,
        MaxActive:   maxActive,
        IdleTimeout: MaxIdleTimeout * time.Second,
        Wait:        true,
        Dial: func() (redis.Conn, error) {
            con, err := redis.Dial("tcp", conf["Host"].(string),
                redis.DialPassword(conf["Password"].(string)),
                redis.DialDatabase(int(conf["Db"].(int64))),
                redis.DialConnectTimeout(timeout*time.Second),
                redis.DialReadTimeout(timeout*time.Second),
                redis.DialWriteTimeout(timeout*time.Second))            if err != nil {                return nil, err 
            }   
            return con, nil 
        },  
    }
}//        rc := RedisClient.Get()//            defer rc.Close()//     if conn.Err() != nil {  //TODO}

他にもいくつか注意すべき点があります.
  • MaxActive最大接続数、すなわち最大tcp接続数は、一般的には大きな構成が推奨されますが、オペレーティングシステムファイルハンドルの数を超えないでください(centosではulimit-nで表示できます).
  • MaxIdle最大アイドル接続数は、このような複数の接続が事前に待機しているが、タイムアウト時間が経過すると閉じます.
  • IdleTimeoutアイドル接続タイムアウト時間ですが、redisサーバのタイムアウト時間より短く設定する必要があります.そうでなければ、サービス側がタイムアウトし、クライアントが接続を維持しても始まらない.
  • Waitこれは便利な構成です.多くの東抄本が写した文章は何も言わなかった.最大接続を超えた場合は、エラーを報告するか、待つか.

  • よくあるエラー


    接続プールが消耗した

    redigo: connection pool exhausted

    redigoはよくこのような新聞の間違いがあります.この問題をredigoソースコードから分析します.
        // Handle limit for p.Wait == false.    if !p.Wait && p.MaxActive > 0 && p.active >= p.MaxActive {
            p.mu.Unlock()        return nil, ErrPoolExhausted
        }

    Wait=false、現在有効な接続>=最大接続数でこのエラーが報告されます.この問題を解決するには、このパラメータを変更します.
  • MaxActiveはMaxActiveを大きくすることができます(一般的に5001000に設定しても問題はありません).しかし、redisサーバの負荷が高い場合(redis-server CPUの占有量が見られる)、MaxActiveを大きくするのはあまり意味がありません.やはり実際の状況に応じてバランスをとる必要がある.
  • WaitはWaitをtrueに設定できます.waitの場合は必然的に応答が増大し,応答時間に対する要求が高い場合は,別の方法で解決しなければならない.
  • はまた、ライブラリから読み書き分離によって解決することもできる.特にPHPは、常駐するredis接続プールがないので、複数のスレーブを追加することをお勧めします.

  • 作者:colors_Liuリンク:https://www.jianshu.com/p/d36ab0c1e465出典:簡書簡書の著作権は著者の所有であり、いかなる形式の転載も著者に連絡して授権を得て出典を明記してください.
    転載先:https://blog.51cto.com/5660061/2366599