当我尝试与 redis unix 套接字建立多个(数百个)连接时,我收到此错误。 这是Dial 呼叫的结果。 是什么原因造成的?是 redis 拒绝还是某些操作系统强加了限制?
package main
import (
"fmt"
"sync"
"flag"
"github.com/gomodule/redigo/redis"
)
func client(num int, wg *sync.WaitGroup) {
defer wg.Done()
red, err := redis.Dial("unix", "/tmp/redis.sock")
if err != nil {
fmt.Println(num, "Dial", err)
return
}
defer red.Close()
_, err = red.Do("SELECT", 0)
if err != nil {
fmt.Println(num, "SELECT", err)
return
}
_, err = red.Do("GET", "redplaytest")
if err != nil {
fmt.Println(num, "GET", err)
return
}
}
func main() {
var wg sync.WaitGroup
var count int
flag.IntVar(&count, "n", 1000, "number")
flag.Parse()
for i:= 0; i < count; i++ {
wg.Add(1)
go client(i, &wg)
}
wg.Wait()
fmt.Println("Done")
}
这就是发生的情况,失败的次数因启动而异:
$ ./redplay -n 800
693 Dial dial unix /tmp/redis.sock: connect: resource temporarily unavailable
509 Dial dial unix /tmp/redis.sock: connect: resource temporarily unavailable
217 Dial dial unix /tmp/redis.sock: connect: resource temporarily unavailable
594 Dial dial unix /tmp/redis.sock: connect: resource temporarily unavailable
436 Dial dial unix /tmp/redis.sock: connect: resource temporarily unavailable
Done
看来redis连接队列已满,我必须等待稍后再试。 这就是我设法让它发挥作用的方法:
...
tries := 10
for tries != 0 {
red, err = redis.Dial(red_sock_type, red_sock)
if err == nil {
break
}
if nerr, ok := err.(net.Error); ok && nerr.Temporary() {
time.Sleep(time.Duration(rand.Intn(1000)) * time.Millisecond)
} else {
break
}
tries--
}
...
我遇到了同样的问题,但使用的是 C++ 版本的 Redis 客户端。我试图在获取 ~100 个密钥时重用来自 16 个不同线程的一个连接。
就我而言,它有助于增加参数socket_timeout和connect_timeout。
sw::redis::ConnectionOptions opt;
opt.host = host;
opt.port = port;
opt.socket_timeout = REDIS_SOCKET_TIMEOUT;
opt.connect_timeout = REDIS_CONNECTION_TIMEOUT;
https://github.com/sewenew/redis-plus-plus/issues/604
Go 版本的 Redis 客户端库还应该允许控制超时。检查 Redis 服务器本身的超时也可能有意义。