Как стать автором
Обновить

Приручаем многопоточность в Node.js (часть 4/5: координатор против синхронного кода)

Время на прочтение11 мин
Количество просмотров4.3K
Всего голосов 17: ↑15 и ↓2+13
Комментарии12

Комментарии 12

А не проще ли вынести из главного потока те самые синхронные задачи, чем придумывать какие-то координаторы?

Не проще, если/когда вы над этим не властны.

Пример из жизни: процесс принимает стрим текстовых строк, применяет на них регулярку (синхронно, увы!) и, когда совпадение найдено, нарезает текстовый блок до следующего совпадения. Примерно так: ......AAA......BB.... А блок (AAA, BB) отдается как раз вспомогательным потокам на CPU-intensive парсинг.

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

Offtopic про регулярки. Если их можно заменить на поиск через indexOf или еще как-то, то желательно заменить. Сталкивался с очень серьезным падением производительности (на порядок) в нагруженном сервисе именно на поиске подстрок через регулярки.

Согласен на 100%. Но многие регулярки так не заменишь - например, банальный поиск первого непробельного символа /\S/.

можно сравнить по скорости с поиском через цикл по строке и проверкой на пробел, \t, \r, \n, \f

А в целом, да, я конечно признаю, что без регулярок местами очень плохо.

Это будет реализация в прикладном коде ровно того же, что делает RE-библиотека в коде скомпилированном. Явно не быстрее.

Я в продакшене всё такое в отдельные микросервисы выношу. Апи отдельно, агрегаторы отдельно. Между ними БД. Апи горизонтально масштабируются отдельно от агрегаторов. Получается очень неплохо.

Исключительно вопрос эффективности использования выделенных ресурсов. Очевидно, что передача по сети даже в рамках одного ДЦ медленее, чем передача в поток через память, а ресурсов требует больше.

Если нужно посчитать один раз и результат всегда уникален - да, вы правы. В остальных случаях мой способ чаще всего будет эффективнее.

А можно чуть подробнее? Вроде если считать надо не один раз, и результат неуникален, то это решается просто кэшированием.

Не всё можно закешировать. Кейс - есть несколько внешних систем, мы из них данные собираем, после планируем их по апи отдавать. Можно было бы кешированием, но если нам нужны фильтры, сортировка и пагинация по этим данным - кеши раздует очень сильно. Мы решаем что будем данные отдавать из памяти, но тогда у нас блокировка одного потока, пока там какие-нибудь хитрые вычисления - апи не отдаст ничего. Тогда мы можем как в этой статье выносить в отдельные потоки. Но тогда при масштабировании у нас будет много копий данных, если они большие - нужна БД. Если по данным сложные фильтры - документная или реляционная. Но если мы хотим горизонтальное масштабирование - нам нужно будет много инстансоа апи, но агрегаторов совсем не много. И тогда исчезает смысл распаралеливания и всяких хитрых механизмов переключения, получения данных и тп. Пусть за нас это ОС решает, там уже отлажено, к тому же это могут быть разные машины и даже континенты земли. И тогда порезать по паттерну когда апи отдельно, агрегаторы отдельно - уже выходит лучшим вариантом.

В целом могут быть кейсы когда поток будет лучше, вот тот же вариант когда нужно что-то считать вместе и быстро - потоки будут быстрее, лучше и эффективнее. Но нужно понимать когда реально стоит, потому что это действительно быстрее, а когда это велосипед. Только лишь от этого предостерегаю :)

Плюсы потоков:

  • Потоки дешевле процессов по ресурсам для операционки.

  • В поток не надо передавать данные через сеть как обычно в микросервис.

  • Поток всегда доступен, а микросервис может оказаться не доступен (или очередь куда вы шлете задания микросервису).

Плюсы микросервисов:

  • Можно докинуть количество микросервисов если очередь задач слишком большая (количество потоков обычно регулирует основной процесс и вмешаться тут сложнее).

  • Можно развернуть на разных машинах (и на разных цодах) и не упереться в вычислительные лимиты.

  • Один микросервис может выполнять задачи для разных заказчиков в то время как поток работает на пользу основного процесса.

  • А также следует учитывать полное разделение кода и возможность применения других языков и фреймворков для микросервиса.

Возможно, я много чего еще упустил, но как мне кажется, уже исходя из этих плюсов можно смотреть как лучше реализовать ту или иную сложную вычислительную задачу.

Зарегистрируйтесь на Хабре, чтобы оставить комментарий