Экземпляры против ядер при использовании EC2

12

Работая над проектами, которые часто называют «средними данными», я смог распараллелить мой код (в основном для моделирования и прогнозирования в Python) в одной системе в любом месте от 4 до 32 ядер. Сейчас я смотрю на масштабирование до кластеров в EC2 (возможно, с помощью StarCluster / IPython, но также и для других предложений) и был озадачен тем, как согласовать распределение работы по ядрам в экземпляре и экземплярах в кластере.

Является ли практичным даже распараллеливание между экземплярами, а также между ядрами в каждом экземпляре? Если да, может ли кто-нибудь кратко рассказать о плюсах и минусах запуска множества экземпляров с несколькими ядрами в каждом по сравнению с несколькими экземплярами со многими ядрами? Существует ли эмпирическое правило для выбора правильного соотношения между экземплярами и ядрами для каждого экземпляра?

Пропускная способность и оперативная память - нетривиальные проблемы в моих проектах, но легко заметить, когда это узкие места и перестройка. Я полагаю, гораздо сложнее сравнить правильное сочетание ядер с экземплярами без повторного тестирования, и мои проекты слишком сильно различаются, чтобы какой-либо отдельный тест можно было применять при любых обстоятельствах. Заранее спасибо, и если я только что не смог правильно его найти, не стесняйтесь указывать мне правильный ответ где-нибудь еще!

Therriault
источник

Ответы:

11

При использовании IPython вам почти не нужно об этом беспокоиться (за счет некоторой потери эффективности / больших накладных расходов на связь). Плагин параллельного IPython в StarCluster по умолчанию запускает один движок на каждое физическое ядро ​​на каждом узле (я думаю, что это настраивается, но не уверен, где). Вы просто запускаете что угодно на всех движках, используя API DirectView (map_sync, apply_sync, ...) или магические команды% px. Если вы уже используете IPython параллельно на одном компьютере, его использование в кластере ничем не отличается.

Решая некоторые из ваших конкретных вопросов:

«Как согласовать распределение работы между ядрами в экземпляре и экземплярами в кластере» - вы получаете один механизм на ядро ​​(как минимум); работа автоматически распределяется по всем ядрам и по всем экземплярам.

«Является ли практичным даже распараллеливание между экземплярами, а также между ядрами в каждом экземпляре?» - Да :) Если код, который вы запускаете, смущающе параллелен (точно такой же алгоритм для нескольких наборов данных), то вы можете в основном игнорировать, где работает конкретный движок. Если ядро ​​требует много связи между двигателями, то, конечно, вам нужно структурировать его так, чтобы двигатели в основном связывались с другими двигателями на той же физической машине; но я думаю, что такая проблема не идеально подходит для IPython.

«Если так, то может ли кто-нибудь кратко рассказать о плюсах и минусах запуска множества экземпляров с несколькими ядрами в каждом по сравнению с несколькими экземплярами со многими ядрами? Существует ли эмпирическое правило для выбора правильного соотношения экземпляров и ядер в каждом экземпляре? " - использовать самые большие экземпляры c3 для задач, связанных с вычислениями, и наименьшие для проблем, связанных с пропускной способностью памяти; для проблем, связанных с передачей сообщений, также используйте самые большие экземпляры, но попробуйте разделить проблему так, чтобы каждый раздел работал на одном физическом компьютере, и большая часть передачи сообщений находилась в одном и том же разделе. Проблемы, которые будут выполняться значительно медленнее на N четырехкратных экземплярах c3, чем на 2N double c3, встречаются редко (искусственный пример может заключаться в использовании нескольких простых фильтров на большом количестве изображений, когда вы просматриваете все изображения для каждого фильтра, а не все фильтры для то же изображение).

Алекс я
источник
1
Я думаю, вы должны заметить, что для процессов на одной машине вы можете использовать переменные карты памяти с помощью joblib / Numpy. Вы теряете эту способность для процессов на разных машинах.
Галламин
11

Общее правило - не распространять, пока не придется. Обычно более эффективно иметь N серверов определенной емкости, чем 2N серверов вдвое меньше. Доступ к данным будет в большей степени локальным и, следовательно, быстрым в памяти по сравнению с медленным в сети.

В определенный момент масштабирование одной машины становится неэкономичным, поскольку стоимость дополнительных ресурсов масштабируется более чем линейно. Однако эта точка все еще удивительно высока.

В частности, на Amazon экономия каждого типа экземпляра может сильно различаться, если вы используете экземпляры спотового рынка. Цены по умолчанию более или менее означают, что один и тот же объем ресурсов стоит примерно одинаково, независимо от типа экземпляра, который может сильно различаться; большие экземпляры могут быть дешевле, чем маленькие, или N маленьких экземпляров могут быть намного дешевле, чем один большой компьютер с эквивалентными ресурсами.

Одним из важных соображений здесь является то, что вычислительная парадигма может сильно измениться при переходе с одной машины на несколько машин. Компромиссы, возникающие из-за накладных расходов на связь, могут заставить вас, например, принять параллельную для данных парадигму для масштабирования. Это означает другой выбор инструментов и алгоритмов. Например, SGD выглядит совсем иначе в памяти и в Python, чем в MapReduce. Таким образом, вы должны рассмотреть это перед распараллеливанием.

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

Шон Оуэн
источник
6

При всех равных условиях (стоимость, производительность процессора и т. Д.) Вы можете выбрать наименьший экземпляр, который может хранить весь мой набор данных в памяти и масштабироваться. Сюда

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

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

Если ваши данные не помещаются в памяти одной системы, вам, конечно, нужно распределить их по экземплярам. Затем необходимо сбалансировать задержку памяти (лучше во многих случаях) с задержкой в ​​сети (лучше с меньшим количеством экземпляров), но, учитывая природу EC2, держу пари, что вы часто предпочитаете работать с несколькими жирными экземплярами.

damienfrancois
источник