bigywater.tech
Redis · 114

Redis 连接数与文件描述符

Redis 能同时接多少个连接?连接满了会怎样?一个连接占多少资源?这篇把 maxclients、文件描述符、空闲超时逐个验证:包括「maxclients 满了连管理连接都进不去」这个容易被忽略的后果。

10000
默认 maxclients(本机 ulimit -n 足够大,没有被自动降低)
第 100 个
maxclients 100 时,开始被拒的连接序号(ERR max number of clients reached)
17 KB / 个
1000 个空闲连接的 used_memory 增量平均值(每个还占 1 个文件描述符)

默认值

实测 · 本机执行输出
> CONFIG GET maxclients
1) "maxclients"
2) "10000"
  INFO clients: maxclients = 10000  connected_clients = 1
  当前 shell 的 ulimit -n = (1048576, 9223372036854775807)
  redis 日志里关于 maxclients / 文件描述符的行: []

maxclients 默认 10000;实际可用还受进程的文件描述符上限(ulimit -n)限制——Redis 启动时会检查,不够就自动调小 maxclients 并在日志里说明。本机上限是 1048576,没有触发。

连接满了

实测 · 本机执行输出
  尝试 120 个连接:成功 100(含最初那个 c),被拒 21;第一个被拒的是第 100 个:b'-ERR max number of clients reached\r\n'
  INFO stats rejected_connections = 21  total_connections_received = 102

maxclients 100:第 100 个及以后的连接收到 -ERR max number of clients reached 后被关闭,INFO stats 的 rejected_connections 是 21。此时任何新连接都进不去,包括你想用来登录排查的那个:我的脚本要先关掉一个已有连接,才能读到 INFO。

空闲超时

实测 · 本机执行输出
  空闲连接被关闭用了 2.7 秒(对端读到 b'',即 EOF)
  统计: 4 个连接被接受过;connected_clients = 1

timeout 2:空闲连接在 2.7 秒后被关闭,对端读到 EOF。比配置的 2 秒略晚,因为空闲检查是后台周期任务(第 110 篇)。默认 timeout 0 表示不关闭空闲连接。

每个连接的成本

实测 · 本机执行输出
  1000 个连接:connected_clients = 1001,used_memory +17.2 MB(每个连接约 16.8 KB),Redis 进程打开的文件描述符 1016 个(lsof 行数)

1000 个空闲连接:used_memory 增加约 17 MB(每个约 16.8 KB),lsof 显示进程打开 1016 个文件描述符(每个连接 1 个,加上 Redis 自己的若干个)。第 112 篇用 mem_clients_normal 得到的是每个约 8.5 KB,口径不同(这里含连接引起的全部分配)。所以 10000 个连接要预留百余 MB 内存与一万多个描述符。

分步演示:连接的上限与成本

Redis 连接数与文件描述符
本步的对象

    本文用到的工具与边界

    • 本机 macOS 27 / Redis 8.10.2 独立实例(本机回环端口,save 关闭),redis-cli 风格输出由自写的 RESP 客户端打印;计时用 time.perf_counter,数字每次运行会有小幅抖动。maxclients 演示为临时设成 100;文件描述符数来自 lsof;timeout 演示为 2 秒
    • 没有验证:ulimit -n 小于 maxclients 时 Redis 自动降低的提示原文、tcp-backlog 与 somaxconn 对突发连接的影响、TLS 连接的额外开销、被 timeout 关闭的连接在客户端库里的表现
    京ICP备2026067502号-1京公网安备11010502063487号