Redis Unix Socket大量连接报错connect: resource temporarily unavailable排查
当尝试建立数百个Redis Unix Socket连接时,Dial调用返回错误"connect: resource temporarily unavailable",请问该错误是由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主动拒绝连接,原因如下:
- 错误信息"resource temporarily unavailable"对应系统底层的
EAGAIN/EWOULDBLOCK错误码,当系统或进程的套接字相关资源耗尽时会触发。常见场景包括:单个进程能打开的文件描述符(每个Socket连接对应一个文件描述符)达到上限、系统级的套接字连接队列耗尽等。 - 如果是Redis主动拒绝连接,会返回Redis层面的明确错误,比如"max number of clients reached"(达到最大客户端数限制),而非这种系统级的连接失败错误。
- 你的代码并发发起大量连接,操作系统默认对单个进程的文件描述符限制通常是1024,当发起800个连接时,加上进程本身已打开的其他文件描述符,很容易触及这个限制,从而触发错误。
验证与解决方向
- 检查客户端进程的文件描述符限制:执行
ulimit -n查看当前软限制,默认一般为1024。 - 临时调整文件描述符上限:执行
ulimit -n 4096(仅对当前终端会话有效),再运行测试程序即可验证。 - 永久调整限制:修改系统配置文件(如
/etc/security/limits.conf),添加或修改* soft nofile 4096和* hard nofile 4096,重启后生效。 - 若怀疑Redis端的限制,可检查Redis配置中的
maxclients参数,但该限制触发时的错误信息与当前报错不符,优先级低于系统资源限制排查。
内容的提问来源于stack exchange,提问作者Sergey
相关产品推荐
相关产品推荐

