一个数据库服务器只拥有有限的链接资源,一旦全部的链接资源都在使用,那么其它须要链接的资源就只能等待释放链接资源。因此,在链接资源有限的状况下,提升单位时间的链接的使用效率,缩短链接时间,就能显著缩短请求时间。git
因此就有了链接池的概念,在初始化时,建立必定数量的链接,先把全部链接存起来,而后,谁须要使用,从这里取走,干完活立马放回来。 若是请求数超出链接池容量,那么就排队等待或者直接丢弃掉。这样就能够省掉每次都建立和关闭链接的资源消耗和时间。github
若是不使用链接池,那么,每次传输数据,咱们都须要耗费大量的系统资源进行建立链接,收发数据,关闭链接。很明显,重复建立链接 关闭链接这样的消耗是能够节省。web
先看下简单的使用案例。
首先固然是下载类库包
go get github.com/gomodule/redigo/redis
贴下简单的使用代码redis
package main import ( red "github.com/gomodule/redigo/redis" "time" "fmt" ) type Redis struct { pool *red.Pool } var redis *Redis func initRedis() { redis = new(Redis) redis.pool = &red.Pool{ MaxIdle: 256, MaxActive: 0, IdleTimeout: time.Duration(120), Dial: func() (red.Conn, error) { return red.Dial( "tcp", "127.0.0.1:6379", red.DialReadTimeout(time.Duration(1000)*time.Millisecond), red.DialWriteTimeout(time.Duration(1000)*time.Millisecond), red.DialConnectTimeout(time.Duration(1000)*time.Millisecond), red.DialDatabase(0), //red.DialPassword(""), ) }, } } func Exec(cmd string, key interface{}, args ...interface{}) (interface{}, error) { con := redis.pool.Get() if err := con.Err(); err != nil { return nil, err } defer con.Close() parmas := make([]interface{}, 0) parmas = append(parmas, key) if len(args) > 0 { for _, v := range args { parmas = append(parmas, v) } } return con.Do(cmd, parmas...) } func main() { initRedis() Exec("set","hello","world") fmt.Print(2) result,err := Exec("get","hello") if err != nil { fmt.Print(err.Error()) } str,_:=red.String(result,err) fmt.Print(str) }
使用类库操做链接池就比较简单,只要从链接池获取一个链接,进行数据操做,而后关闭链接。链接池对链接的建立 回收等的管理,都是链接池内部实现。
执行看下结果是否是预想的数据库
go build -o test_web.bin ./test_web.bin 2world
结果跟预想的一毛同样服务器
MaxIdle:最大的空闲链接数,表示即便没有redis链接时依然能够保持N个空闲的链接,而不被清除,随时处于待命状态。
MaxActive:最大的链接数,表示同时最多有N个链接。0表示不限制。
IdleTimeout:最大的空闲链接等待时间,超过此时间后,空闲链接将被关闭。若是设置成0,空闲链接将不会被关闭。应该设置一个比redis服务端超时时间更短的时间。
DialConnectTimeout:链接Redis超时时间。
DialReadTimeout:从Redis读取数据超时时间。
DialWriteTimeout:向Redis写入数据超时时间。app
链接流程大概是这样的
1.尝试从空闲列表MaxIdle中,得到一个可用链接;若是成功直接返回,失败则尝试步骤2
2.若是当前的MaxIdle < 链接数 < MaxActive,则尝试建立一个新链接,失败则尝试步骤3tcp
目前为止,链接池的问题只遇到过一次问题,并且是在测试环境的,当时的配置是测试
DialConnectTimeout:time.Duration(200)*time.Millisecond DialReadTimeout:time.Duration(200)*time.Millisecond DialWriteTimeout:time.Duration(200)*time.Millisecond
配置的都是200毫秒。有一次使用hgetall的时候,就一直报错,大概相似下面的提示ui
read tcp 127.0.0.1:6379: i/o timeout
字面意思就是 read tcp 超时,可能某些写入大点数据的时候也会报,write tcp timeout。
后来将读写超时时间都改成1000毫秒,就再也没有出现过相似的报错。
固然了,想了解更多的Redis使用,能够看下官方的文档,里面有各类状况的各类说明。
https://github.com/gomodule/redigo/