2013-09-02 2 views
22

Может ли кто-нибудь объяснить, что является узким местом каждого метода параллелизма?Что больше всего использует многопроцессорные многопортовые серверы VS?

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

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

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

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

ответ

54

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

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

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

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

В этой дискуссии немало ресурсов. Просмотрите книги Джесси Сторимера по этим темам, working with ruby threads и working with unix processes; read this quick summary of preforking servers by ryan tomayko, и google для получения дополнительной информации.

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

+0

Спасибо Стюарту за отличное разъяснение !! – Ryan

+0

рубин 2.0 является «копией на дружественной записи» означает, что GC не будет делить общий доступ с копией на страницах записи в куче. с 1.9 вы отделите кучу единорогов, и GC запустит и переместит объекты и полностью уничтожит любое преимущество совместного использования COW, которое вы могли бы иметь между этими процессами до начала GC. – lamont

3

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

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

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

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

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

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

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

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

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

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

 Смежные вопросы

  • Нет связанных вопросов^_^