我的程序如下,目的就是为了测试,高并发下读取 redis 会出现什么问题
```
package main
import (
"fmt"
"time"
"github.com/garyburd/redigo/redis"
)
var pool *redis.Pool
type User struct {
ID int `json:"id"`
Name string `json:"name"`
Password string `json:"password"`
}
func init() {
pool = &redis.Pool{
// 初始化链接数量
MaxIdle: 16,
MaxActive: 0,
IdleTimeout: 300 * time.Second,
Dial: func() (redis.Conn, error) {
return redis.Dial("tcp", "127.0.0.1:6379")
},
}
}
func idIncr(conn redis.Conn) (id int, err error) {
res, err := conn.Do("incr", "users_id_for_test")
if err != nil {
fmt.Printf("id incr error: %v\n", err)
return
}
id = int(res.(int64))
fmt.Printf("id: %v\n", id)
return
}
func Register() (err error) {
conn := pool.Get()
defer conn.Close()
// id 自增 1,作为下个用户 id
id, err := idIncr(conn)
if err != nil {
return
}
_, err = conn.Do("rpush", "usersList", id)
if err != nil {
fmt.Printf("set user to reids error: %v", err)
return
}
return
}
// 测试高并发下操作redis
func main() {
for i := 0; i < 1000; i++ {
go Register()
}
time.Sleep(10 * time.Second)
}
````
运行程序后有如下报错:
```
....
id incr error: read tcp 127.0.0.1:59699->127.0.0.1:6379: read: connection reset by peer
id incr error: read tcp 127.0.0.1:59701->127.0.0.1:6379: read: connection reset by peer
id incr error: read tcp 127.0.0.1:59740->127.0.0.1:6379: read: connection reset by peer
....
```
多次测试,发现每次有 300 左右的记录能够插入成功。应该是高并发下,可用 redis 连接数不够导致的问题,有没有了解细节的大佬,能给个完整的讲解?
<a href="/user/jarlyyn" title="@jarlyyn">@jarlyyn</a> 不限制活跃连接数有问题吗? 在我的这个场景中 goroutine 峰值 1001,redis maxclient
设置为 10000 有什么问题?不限制活跃连接数难不成连接数会飙升到 1000 以上?
#2
更多评论
这个要和你redis配置相匹配。
连接池主要解决两个问题,1是防止客户端打开的请求数量超过服务器端,2是避免重复新建和关闭的消耗。
实际上,合适的链接池的效率也比一股脑儿把请求全发过去的效率要高。
而且你已经用了这个包的pool了,为啥不用pool功能……
#3