0

我正在运行一个 4 核 Amazon EC2 实例(m3.xlarge),它有 200.000 个并发连接,没有资源问题(每个核心在 10-20%,内存在 2/14GB)。无论如何,如果我向所有首先连接到 cpu-core 的用户发出消息,则会在几毫秒内得到它,但最后一个连接的用户会延迟 1-3 秒,并且每个 CPU 内核会在 1-2 秒内达到 100% . 即使在“仅”50k 并发用户(每个核心 12.5k)时,我也注意到了这个问题。

如何减少延迟?

我尝试将 redis-adapter 更改为 mongo-adapter 没有区别。

我使用此代码在多个 cpu 核心上获得粘性会话:

https://github.com/elad/node-cluster-socket.io

测试非常简单:客户端只是连接,什么都不做。服务器仅侦听消息并向所有人发出。

编辑:我用 50k 客户端测试了没有任何集群/适配器逻辑的单核,结果相同。

我在一个包中发布了服务器、单核服务器、基准和 html 客户端:https ://github.com/MickL/socket-io-benchmark-kit

4

1 回答 1

1

好的,让我们分解一下。四个核心上的 200,000 个用户。如果分布完美,则每个核心有 50,000 个用户。因此,如果向给定用户发送一条消息每个 CPU 时间需要 0.1 毫秒,那么将它们全部发送需要 50,000 * .1 毫秒 = 5 秒。

如果您在此期间看到 CPU 利用率达到 100%,那么瓶颈可能是 CPU,并且您可能需要更多内核来解决这个问题。但是,也可能存在其他瓶颈,例如网络带宽、网络适配器或 redis 进程。因此,要立即确定的一件事是您的端到端时间是否与您拥有的集群/CPU 数量成正比?如果降到 2 个核心,端到端时间会翻倍吗?如果你去8,它会下降一半吗?如果两者都是,那是个好消息,因为这意味着您目前可能只遇到 CPU 瓶颈,而不是其他瓶颈。如果是这种情况,那么您需要通过检查 node-cluster-socket.io 代码并找到优化您的特定情况的方法来弄清楚如何使跨多个集群的 200,000 个发射更有效。

最优化的代码可能是让每个 CPU 完成所有的内务处理以准确收集它需要发送给所有 50,000 个用户的内容,然后每个 CPU 很快执行一个紧密循环,一个接一个地发送 50,000 个网络数据包。我无法从 redis 适配器代码中判断这是否会发生。

最糟糕的情况是某个进程获取所有 200,000 个套接字 ID,然后进入循环以发送到每个套接字 ID,在该循环中,它必须在 redis 上查找哪个服务器包含该连接,然后向该服务器发送消息告诉它发送到那个套接字。这将比指示每个服务器只向其所有连接的用户发送消息效率低很多。

值得尝试(通过研究代码)找出 socket.io + redis 组合在这个范围内的哪个位置。

哦,如果您为每个套接字使用 SSL 连接,那么您还需要在每个发送操作上投入一些 CPU 来加密。有一些方法可以从常规 CPU 中卸载 SSL 处理(使用额外的硬件)。

于 2017-09-08T13:41:10.610 回答