慢速磁盘 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 进程来提供静态文件,甚至完全使用单独的专用服务器?
我能想到的有以下几点:
- "waiting to be served" HTTP 请求将用完有限数量的可用并发 TCP 连接
- "waiting to be served" HTTP 请求也将耗尽一些 RAM
- 系统文件应该驻留在不会忙于提供静态文件的磁盘上
我们目前还不能在现实世界中测试这种情况,所以我非常感谢能收到任何有类似经历的人的来信。这可能需要我们重新考虑架构,这是我们最好早日发现的东西。
如果您有很多来自客户端的请求,您需要通过集群使用负载均衡器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 的建议,以尝试完全删除服务来自您的应用程序的静态文件。
我在一个小团队中开发一个单页应用程序,该应用程序严重依赖 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 进程来提供静态文件,甚至完全使用单独的专用服务器?
我能想到的有以下几点:
- "waiting to be served" HTTP 请求将用完有限数量的可用并发 TCP 连接
- "waiting to be served" HTTP 请求也将耗尽一些 RAM
- 系统文件应该驻留在不会忙于提供静态文件的磁盘上
我们目前还不能在现实世界中测试这种情况,所以我非常感谢能收到任何有类似经历的人的来信。这可能需要我们重新考虑架构,这是我们最好早日发现的东西。
如果您有很多来自客户端的请求,您需要通过集群使用负载均衡器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 的建议,以尝试完全删除服务来自您的应用程序的静态文件。