NodeJS — разветвленные процессы (1 виртуальная машина, несколько процессоров) VS несколько виртуальных машин, 1 процесс

Я разрабатываю службу в NodeJS, которая будет создавать текстовые файлы из изображений, используя оболочку узла для механизма OCR tesseract. Я хочу, чтобы это была постоянно работающая служба, запускаемая и перезапускаемая (при сбое) выскочкой.

У меня есть возможность сделать серверы (виртуальные машины, на которых это будет работать) многоядерными машинами с большой оперативной памятью и дисковым пространством, или у меня есть возможность создать 4 или 5 небольших виртуальных машин с одним ядром каждая, 1 ГБ ОЗУ и относительно небольшой размер диска.

При первом подходе мне пришлось бы разветвлять различные дочерние процессы, чтобы использовать все ядра, что усложняет код. С другой стороны, у меня есть только одна виртуальная машина, о которой нужно беспокоиться. При втором подходе мне не нужно беспокоиться о разветвлении дочерних процессов, но мне придется создать и настроить несколько виртуальных машин.

Есть ли другие плюсы и минусы каждого подхода, о которых я не подумал?


person AyushISM    schedule 02.09.2016    source источник
comment
Какой подход лучше и почему? звучит так, будто вы спрашиваете кучу мнений, которые здесь строго не по теме. Не могли бы вы перефразировать последнее предложение, в котором запрашиваются факты, а не мнение, чтобы оно было четко по теме.   -  person jfriend00    schedule 02.09.2016


Ответы (1)


Я бы не стал разбивать виртуальные машины на разделы, так как это означает, что вы, скорее всего, в конечном итоге будете тратить ОЗУ и ЦП впустую — вполне вероятно, что вы обнаружите, что одна виртуальная машина использует 100% своих ресурсов, а другая простаивает. Есть также нетривиальные накладные расходы, связанные с запуском 5 операционных систем вместо одной.

Почему вы рассматриваете возможность разветвления многих процессов? Если вы используете правильную библиотеку, в этом не будет необходимости.

Многие библиотеки tesseract для npm написаны плохо. Это ультра-упрощенные привязки к коду tesseract C. В JS вы вызываете функцию recognize() аддона, которая просто вызывает функцию Recognize() tesseract, которая блокирует работу с интенсивным использованием ЦП. Это означает, что вы выполняете распознавание в основном потоке V8, что, как мы знаем, запрещено. Я предполагаю, что именно поэтому вы рассматриваете возможность разветвления процессов, поскольку каждый из них сможет одновременно выполнять только одну операцию блокировки OCR.

Вместо этого вам нужна библиотека, в которой OCR работает в отдельном потоке. Например, tesseract_native. Он правильно разработан: он использует libuv для вызова tesseract в рабочем потоке.

libuv поддерживает пул рабочих потоков, поэтому вы можете иметь столько одновременных операций OCR, сколько у вас есть ядер, и все это в одном процессе.

person josh3736    schedule 02.09.2016
comment
Просто из любопытства, есть ли много популярных/хорошо написанных библиотек npm, которые используют libuv для выполнения интенсивной работы процессора неблокирующим образом? Если да, то почему при разработке экспресс-приложения приходится разветвлять процессы (используя модуль кластера)? Можно ли было также написать экспресс для автоматической обработки запросов в отдельных рабочих потоках? - person AyushISM; 02.09.2016
comment
Это то, сколько основных модулей реализовано. Например, crypto использует libuv для выполнения дорогостоящих операций в рабочем потоке. Есть много других модулей npm, которые используют libuv для выполнения работы (обычно вызывая нативную библиотеку C/C++) в рабочем потоке — примеры включают bcrypt, serialport, edge (клей .NET) и многие другие, которые обеспечить привязку к собственному коду. - person josh3736; 02.09.2016
comment
Однако обращение к собственной библиотеке в рабочем потоке — это другой класс проблем, чем реализация многопоточного JavaScript-кода. V8 (движок JS узла) не позволяет совместно использовать память между потоками JS, поэтому чистая библиотека JS, такая как экспресс, не может автоматически запускать функции обработчика маршрутов в отдельных потоках. (сам узел не поддерживает создание новых потоков V8 — есть модули, которые создают новые потоки V8, но вы не получаете доступ к require.) Таким образом, мы распределяем нагрузку JS, создавая новые процессы. - person josh3736; 02.09.2016