Подтвердить что ты не робот

Что больше всего используют мультипроцессы VS многопоточных серверов?

Может ли кто-нибудь объяснить, в чем узкое место каждого метода concurrency?

Серверы, такие как Unicorn (на основе процесса) Puma (на основе потоков).

Поддерживает ли каждый метод процессорные ядра? потоки? или просто тактовую частоту? или специальную комбинацию?

Как определить оптимальные характеристики процессора, необходимые для использования выделенных серверов?

и как определить лучшую рабочую сумму в случае Единорога или количество потоков в случае Puma?

4b9b3361

Ответ 1

Единорог основан на процессе, что означает, что каждый экземпляр рубина должен существовать в своем собственном процессе. Это может быть в области 500 МБ для каждого процесса, который быстро разрядит системные ресурсы. Puma, основанный на потоках, не будет использовать тот же объем памяти, чтобы ТЕОРЕТИЧЕСКИ достичь того же количества concurrency.

Единорог, поскольку выполняется несколько процессов, будет parallelism между различными процессами. Это ограничено вашими ядрами процессора (больше ядер может одновременно запускать больше процессов), но ядро ​​переключается между активными процессами, поэтому может быть запущено более 4 или 8 процессов (хотя бы у многих ядер). Вы будете ограничены вашей машинной памятью. До недавнего времени рубин не был дружественным по копированию на запись, а это означало, что у КАЖДОГО процесса была собственная унаследованная память (единорог - это предпроккерный сервер). Ruby 2.0 совместим с копированием на запись, что может означать, что единорогу на самом деле не придется загружать все дочерние процессы в памяти. Я не на 100% понимаю это. Читайте о копировании на запись и проверьте jessie storimer потрясающую книгу, "работающую с процессами unix". Я уверен, что он накрыл его там.

Puma - это многопоточный сервер. MRI Ruby, из-за блокировки глобального интерпретатора (GIL), может запускать только одну задачу с привязкой к ЦП одновременно (см. Эпизод 127 ruby ​​tapas, parallel fib). Он переключит контекст между потоками, но пока это задача, связанная с процессором (например, обработка данных), она будет выполнять только один поток выполнения. Это становится интересным, если вы запускаете свой сервер с другой реализацией Ruby, например JRuby или Rubinius. Они не имеют GIL и могут обрабатывать много информации параллельно. JRuby довольно быстро, и хотя Rubinius медленнее по сравнению с MRI, многопоточность Rubinius обрабатывает данные быстрее, чем MRI. Однако во время неблокирующего ввода-вывода (например, для записи в базу данных, создания веб-запроса) MRI переключит контекст на неиспользуемый поток и там будет работать, а затем вернется к предыдущему потоку, когда информация будет возвращена.

Для Unicorn я бы сказал, что узким местом является память и тактовая частота. Для Puma я бы сказал, что узким местом является ваш выбор интерпретатора (MRI vs Rubinius или JRuby) и тип работы, выполняемой вашим сервером (много задач с привязкой к процессору против неблокирующего IO).

В этой дискуссии много полезных ресурсов. Просмотрите книги Джесси Сторимера по этим темам, работает с рубиновыми нитями и работает с unix-процессы; прочитайте это краткое изложение предпродажных серверов от ryan tomayko и google для получения дополнительной информации.

Я не знаю, какая лучшая рабочая сумма для Unicorn или Puma в вашем случае. Лучше всего сделать выполнить тесты производительности и сделать то, что подходит вам. Нет ни одного размера. (хотя я думаю, что стандартом puma является использование пула из 16 потоков и блокировка его при этом)

Ответ 2

Puma на самом деле многопоточная и многопроцессорная. Вы можете вызвать его в "кластерном режиме", где он будет выведен из нескольких разветвленных работников, которые будут работать на разных ядрах на МРТ. Поскольку Puma многопоточен, вероятно, он подходит для запуска нескольких процессов, равных количеству ядер на сервере. Таким образом, для 4-х серверного сервера было бы подходящим:

puma -t 8:32 -w 4 --preload

Это будет обрабатывать до 32 одновременных потоков, одновременно до четырех потоков, работающих на процессорах, и должно быть в состоянии максимизировать ресурсы ЦП на сервере. Аргумент --preload предварительно загружает приложение и использует преимущества рубинового 2.0 COW для сборки мусора, чтобы уменьшить использование ОЗУ.

Если ваше приложение тратит значительное время на другие сервисы (службы поиска, базы данных и т.д.), это будет большим улучшением. Когда поток блокируется, другой поток в том же процессе может захватить процессор и работать. Вы можете поддерживать до 32 запросов параллельно в этом примере, в то время как только сбой запуска 4 процессов в ОЗУ.

С Unicorn вам придется разблокировать 32 рабочих, которые могли бы поразить 32 процесса в ОЗУ, что очень расточительно.

Если все ваше приложение будет хрустом CPU, это будет крайне неэффективно, и вы должны уменьшить количество единорогов, а преимущества Puma над Unicorn будут уменьшены. Но в случае с Unicorn вам нужно сравнить ваше приложение и выяснить правильный номер. Puma будет стремиться оптимизировать себя, создавая больше потоков, и ее производительность должна варьироваться от не хуже Unicorn (в чистом CPU) до того, чтобы быть намного лучше, чем Unicorn (в случае приложения, которое спит много).

Конечно, если вы используете Rubinius или JRuby, тогда это не будет соревнование, и вы можете создать один процесс, который запускает многоядерность и обрабатывает все 32 потока.

TL; DR - это то, что я не думаю, что у Unicorn намного больше преимуществ по сравнению с Puma, поскольку Puma фактически использует обе модели.

Конечно, я ничего не знаю о надежности Puma против Unicorn в запуске программного обеспечения для производства в реальном мире. Одна вещь, о которой стоит беспокоиться, это то, что если вы начертаете какое-либо глобальное состояние в одном потоке, это может повлиять на выполнение других запросов одновременно, что может привести к неопределенным результатам. Поскольку Unicorn не использует потоки, проблем с concurrency нет. Я хотел бы надеяться, что к этому времени оба Puma и Rails будут зрелыми по отношению к проблемам concurrency и что Puma можно использовать в производстве. Тем не менее, я не обязательно буду ожидать, что каждый плагин rails и rubygem, который я нашел в GitHub, будут потокобезопасными и ожидаем, что вам придется выполнять дополнительную работу. Но как только вы достаточно успешны, чтобы находить проблемы с потоками в сторонних библиотеках, вы, вероятно, достаточно велики, чтобы не позволить себе расходы на ОЗУ для запуска большого количества процессов Unicorn. OTOH, я понимаю ошибки concurrency, и я хорошо разбираюсь в Ruby, так что стоимость отладки может быть намного меньше для меня, чем стоимость покупки ОЗУ в облаке. YMMV.

Также обратите внимание, что я не уверен, следует ли считать количество гипертекстовых ядер или физических ядер при оценке значения, которое нужно передать на "-w", и вам нужно будет перенести тест самостоятельно, а также проверить, какие значения использовать для -t. Несмотря на то, что даже если вы выполняете вдвое больше процессов, которые вам нужны, планировщик процессов в ядре должен иметь возможность справиться с этим без проблем, пока вы не насытите CPU, и в этом случае у вас будут большие проблемы. Я бы рекомендовал начать процесс для каждого гиперпотокового ядра (на MRI).