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}
他にもいくつか注意すべき点があります.
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}
他にもいくつか注意すべき点があります.
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}
よくあるエラー
接続プールが消耗した
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、現在有効な接続>=最大接続数でこのエラーが報告されます.この問題を解決するには、このパラメータを変更します.
redigo: connection pool exhausted
// Handle limit for p.Wait == false. if !p.Wait && p.MaxActive > 0 && p.active >= p.MaxActive {
p.mu.Unlock() return nil, ErrPoolExhausted
}
作者:colors_Liuリンク:https://www.jianshu.com/p/d36ab0c1e465出典:簡書簡書の著作権は著者の所有であり、いかなる形式の転載も著者に連絡して授権を得て出典を明記してください.
転載先:https://blog.51cto.com/5660061/2366599