我们有3个数字海洋ubuntu Droplet(*不包括nextjs的前端):
后端: 16 个 vcpu | 32GB 内存
数据库MYSQL: 8 个 vcpu | 16GB 内存
REDIS: 4 个 vcpu | 32GB 内存
我们正在运行一个偶尔获得高并发用户的网站。
负载会立即从 0 跳到 90,但除了我们在每一步中都会遇到的系统配置限制之外,它处理得很好。
经过一周的调试问题,我们做了以下工作,解决了瓶颈并跳转到下一个:
在这一切之后,一切似乎都进展顺利。尽管我们开始遇到另一个与每个端口允许的最大打开 TCP 连接数相关的问题,服务器使用该连接来连接到 MYSQL 和 REDIS
我们通过访问从 mysql 和 redis 读取数据的单个端点来运行简单的压力测试 1000个并发请求发送50次,总共50k个连续请求
在 35k 请求标记附近,请求将开始失败,并出现上述错误。经过进一步检查并在进行压力测试时运行
netstat -anlp | grep :3306 | grep TIME_WAIT -wc
,我们注意到数字随着请求的到来不断增长,很快就会达到35k,此时开始出现错误。这些 TIME_WAIT 连接似乎在 60 秒后关闭。经过研究,我们尝试使用 net.ipv4.tcp_fin_timeout = 3 & sysctl -p
将这个数字降低到 3 秒,但无济于事:/ 连接始终保持打开状态 60 秒,这在重负载下造成了很大的瓶颈。
我们该怎么办?
PS:在简单的压力测试下,RAM 和 CPU 的表现都很好。
从Redis使用角度来说,其他的把握较少:
使用与同一服务器的多个连接有什么好处?
您可以拥有一些池,具体取决于您使用的客户端的实现,但是为每个请求创建一个连接是没有用的。
您应该了解限制,使用 Redis 服务器可以有效处理的最大连接量,并重复使用相同的连接。
你还应该了解你使用的客户端的架构,例如如果它是一个多路复用器,即使多个连接也是没有用的。
越来越多的连接发送更多 Redis(或 MYSQL)可以服务的请求只是对资源的滥用,它使用私家车来处理每个请求并坐在交通中,而不是全部转移到公共交通工具上,这并不更快,并且您需要更多的资源。
如果您需要更多 TPS,您应该扩展 Redis,迁移到集群模式并添加更多复制,以便您可以从更多端点读取数据,并且流量在分片之间具有“负载平衡”,与数量相比,连接量应该几乎恒定集群拥有的节点数。
如果使用得当,Redis 将比传入的请求快得多(Valkey,Redis 的 OSS 分支,刚刚发布了具有 100 万 TPS 的 Valkey 8,这超出了大多数应用程序的需要,并且每个请求不需要连接)。
我想对于MySQL来说更是如此,连接量应该由数据库服务请求的能力来决定,并且有一个很小的余量,没有逻辑持有更多。