慢速磁盘 I/O 是否会降低 Node.js 应用程序其余部分的性能?

Does slow disk I/O degrade the performance of rest of the Node.js application?

我在一个小团队中开发一个单页应用程序,该应用程序严重依赖 WebSockets 上的低延迟查询。后端运行在 Node.js + Redis 上。它需要支持数百到数千个并发连接,并且需要在 50 - 100 毫秒(在客户端良好的网络条件下)内处理请求。我们对服务器这部分的初始实现相当满意,它按预期运行。

我们还需要通过 HTTP 提供大量静态文件。这些请求对时间不敏感。由于存储需求较大,出于成本原因,我们希望选择 HDD 阵列而不是 SSD。

慢速磁盘 I/O 是否存在降低 Node.js 应用程序其余部分(仅使用内存数据库的 WebSocket 部分)性能的风险,或者它是否会严格影响服务器的 HTTP / 静态文件服务部分?就我的理解而言,Node.js 具有异步特性,非常适合这种情况,因为它允许 WebSockets 模块在 HTTP 模块等待磁盘 read/write 时正常处理查询?

也许大量 "waiting to be served" HTTP 请求会以某种方式阻塞服务器(毕竟,它们需要存储在某个地方,如果 read/write 可用,则可能无法免费轮询要么),我们需要考虑使用单独的 Node.js 进程来提供静态文件,甚至完全使用单独的专用服务器?

我能想到的有以下几点:

我们目前还不能在现实世界中测试这种情况,所以我非常感谢能收到任何有类似经历的人的来信。这可能需要我们重新考虑架构,这是我们最好早日发现的东西。

如果您有很多来自客户端的请求,您需要通过集群使用负载均衡器API https://nodejs.org/api/cluster.html 您还需要考虑使用缓存,因为 http 和磁盘操作确实很昂贵。如果这些还不够,您只需添加新服务器即可。这就是我做和理解解决高负载问题的方式。

P. S. 我不认为 node.js 是个问题,它是处理静态文件等事情的好平台。你只是有很多请求,你需要用我描述的方法来处理这个问题。

简答:是的有大量risk:p

https://nodejs.org/api/fs.html#fs_threadpool_usage

Threadpool Usage#

All file system APIs except fs.FSWatcher() and those that are explicitly synchronous use libuv's threadpool, which can have surprising and negative performance implications for some applications. See the UV_THREADPOOL_SIZE documentation for more information.

http://docs.libuv.org/en/v1.x/design.html#file-i-o

UV 线程池由系统线程支持,因此缩放配置文件将与应用程序的其余部分大不相同。在我看来,这并不一定要冒更大的风险……不同的硬数据将有助于查看您的应用程序的扩展配置文件。


认为一般最佳做法是尽可能卸载静态文件服务。在您的应用程序前面设置一个能够快速提供静态文件 (nginx) 的代理可能会有所帮助(不是因为它解决了阻止文件系统读取的核心问题,而是因为它 可能 提供更多统一/可预测的性能或缩放,因为它只需要管理服务文件,而您的应用程序需要在用户和服务文件之间进行上下文切换。我个人会研究您使用单独进程或 CDN 的建议,以尝试完全删除服务来自您的应用程序的静态文件。