Влияет ли медленный дисковый ввод-вывод на производительность остальных приложений Node.js?
Я в небольшой команде, занимающейся разработкой одностраничного приложения, которое в значительной степени опирается на запросы с низкой задержкой через WebSockets. Серверная часть работает на Node.js + Redis. Он должен поддерживать от сотен до тысяч одновременных соединений, а запросы должны обслуживаться в течение 50 - 100 мс (при хороших условиях сети на стороне клиента). Мы очень довольны нашей первоначальной реализацией этой части сервера, она работает как положено.
Нам также нужно обслуживать много статических файлов по HTTP. Эти запросы не чувствительны ко времени. Из-за больших требований к хранилищу мы хотели бы выбрать массив жестких дисков вместо SSD по соображениям стоимости.
Существует ли риск медленного дискового ввода-вывода, ухудшающий производительность остальной части приложения Node.js (часть WebSocket только с базой данных в памяти), или это будет строго влиять на HTTP / статический файл, обслуживающий часть сервера? Насколько я понимаю, Node.js с его асинхронной природой хорошо бы подходил для такого рода ситуаций, поскольку он позволял бы модулю WebSockets обрабатывать запросы в обычном режиме, пока модуль HTTP ожидает чтения / записи дисков?
Возможно, большое количество HTTP-запросов "в ожидании обслуживания" может каким-то образом засорить сервер (в конце концов, они должны где-то храниться, и, вероятно, нельзя также опрашивать, доступны ли чтение / запись), и нам нужно Рассмотрите возможность использования отдельного процесса Node.js для обслуживания статических файлов или даже отдельного выделенного сервера?
Я могу думать о следующих вещах:
- HTTP-запрос "в ожидании обслуживания" будет использовать ограниченное количество одновременных доступных TCP-соединений
- HTTP-запросы "в ожидании обслуживания" также будут занимать некоторое количество оперативной памяти
- системные файлы, вероятно, должны находиться на диске, который не будет занят обслуживанием статических файлов.
Мы пока не можем проверить этот сценарий в реальном мире, поэтому я был бы очень рад услышать от кого-либо с подобным опытом. Это может потребовать от нас переосмысления архитектуры, и это то, что мы бы предпочли открыть раньше, чем позже.
2 ответа
Краткий ответ: да Существует огромный риск: р
https://nodejs.org/api/fs.html
Использование Threadpool #
Все API файловой системы, за исключением fs.FSWatcher() и явно синхронных, используют пул потоков libuv, что может иметь неожиданные и отрицательные последствия для производительности некоторых приложений. Смотрите документацию UV_THREADPOOL_SIZE для получения дополнительной информации.
http://docs.libuv.org/en/v1.x/design.html
UV Threadpool поддерживается системными потоками, поэтому профиль масштабирования будет сильно отличаться от остальной части приложения. ИМО, это не так уж и рискованно, просто... разные и точные данные помогут увидеть профиль масштабирования вашего приложения.
Я думаю, что в общем случае лучше всего разгрузить обслуживание статических файлов, если это вообще возможно. Может помочь прокси-сервер перед вашим приложением, способный быстро обслуживать статические файлы (nginx) (не потому, что он решает основную проблему блокировки чтения файловой системы, а потому, что он может предложить более равномерную / предсказуемую производительность или масштабирование, поскольку он только Я должен изучить ваши рекомендации по использованию отдельного процесса или CDN, чтобы попытаться полностью удалить обслуживание статических файлов из вашего приложения.
Если у вас много запросов от клиентов, вам необходимо использовать балансировщик нагрузки через Cluster API https://nodejs.org/api/cluster.html Вам также следует рассмотреть возможность использования кэша, поскольку операции с http и диском действительно дороги. И если этих вещей недостаточно, вы просто добавляете новые серверы. Так я понимаю и решаю проблемы с высокой нагрузкой.
PS Я не думаю, что node.js - это проблема, это хорошая платформа для таких вещей, как обслуживание статических файлов. У вас просто много запросов, и вам нужно решить эту проблему с помощью методов, которые я описал.