Что произойдет, если я начну слишком много фоновых заданий?


13

Мне нужно поработать на 700 сетевых устройствах, используя ожидаемый скрипт. Я могу сделать это последовательно, но пока время выполнения составляет около 24 часов. Это происходит в основном из-за времени, которое требуется для установления соединения, и задержки на выходе этих устройств (старых). Я могу установить два соединения и заставить их работать параллельно, но как далеко я могу это продвинуть?

Я не думаю, что я мог бы сделать все 700 из них одновременно, конечно, есть ограничение на нет. из соединений telnet моя ВМ может управлять.

Если бы я попытался запустить 700 из них в какой-то цикл вроде этого:

for node in `ls ~/sagLogs/`; do  
    foo &  
done

С

  • ЦП 12 ЦП x Intel (R) Xeon (R) CPU E5649 @ 2,53 ГГц

  • Память 47,94 ГБ

Мой вопрос:

  1. Могут ли все 700 экземпляров работать одновременно?
  2. Как далеко я могу пройти, пока мой сервер не достигнет своего предела?
  3. Когда этот лимит будет достигнут, будет ли он ждать начала следующей итерации fooили произойдет сбой коробки?

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


3
Я имел удачу parallel, используя около 50 одновременных заданий. Это отличная середина между параллелизмом от 1 до 700. Еще одна приятная вещь - это то, что она не имеет партии. Одно остановленное соединение остановится только само по себе, а не любое другое. Основным недостатком является управление ошибками. Ни один из этих подходов на основе оболочки не будет корректно обрабатывать ошибки. Вам придется самостоятельно проверять успешность и делать свои собственные повторные попытки.
— Адам

1
Ваша очередь задач может быть 700 сегодня, но может ли размер увеличиться? Следите за расширением пространства подкачки - это означает, что вы достигли предела памяти. И процессор% не является хорошей мерой (для linux / unix), лучше учитывать среднюю нагрузку (длина очереди выполнения).
— ChuckCottrill

1
Самым недавним способом, с помощью которого я прервал производство на своей все еще довольно новой работе, был случайный запуск миллиона плюс кратковременных фоновых заданий одновременно. В них принимали участие виртуальные машины Java (ожидание, ожидание опускало вилы), поэтому последствия были «ограничены» сотнями тысяч файлов отчетов об ошибках, которые нельзя было запустить.
— michaelb958 - GoFundMonica,


1
@KuboMD И до тех пор, пока никто не захочет использовать ваш код.
— 10

Ответы:


17

Могут ли все 700 экземпляров работать одновременно?

Это зависит от того, что вы подразумеваете под одновременно. Если мы привередливы, то нет, они не смогут, если у вас в системе не будет 700 потоков выполнения, которые вы можете использовать (так что, вероятно, нет). Реально, хотя, да, они, вероятно, могут, если у вас достаточно оперативной памяти и / или пространства подкачки в системе. UNIX и его различные дети замечательно хороши в управлении огромными уровнями параллелизма, поэтому они так популярны для крупномасштабного использования высокопроизводительных вычислений.

Как далеко я могу пройти, пока мой сервер не достигнет своего предела?

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

  • Все требования к памяти во время выполнения одной работы, раз 700.
  • Требования к памяти bash для управления таким количеством заданий (bash не так уж и страшен, но управление заданиями не совсем эффективно использует память).
  • Любые другие требования к памяти в системе.

Предполагая, что вы встречаете это (опять же, только с 50 ГБ ОЗУ, вы все равно должны иметь дело с другими проблемами:

  • Сколько процессорного времени будет потрачено bash на управление заданиями? Вероятно, не так много, но с сотнями рабочих мест, это может быть значительным.
  • Какая пропускная способность сети потребуется? Простое открытие всех этих подключений может затопить вашу сеть на пару минут в зависимости от вашей пропускной способности и задержки.
  • Многие другие вещи, о которых я, вероятно, не подумали.

Когда этот лимит будет достигнут, будет ли он ждать начала следующей итерации с foo, или произойдет сбой коробки?

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


Что вам действительно нужно, так это не запускать все задания одновременно. Вместо этого разделите их на пакеты и запустите все задания в пакете одновременно, дайте им закончить, а затем запустите следующий пакет. Для этого можно использовать GNU Parallel ( https://www.gnu.org/software/parallel/ ), но он менее чем идеален в таких масштабах в производственной среде (если вы используете его, не становитесь слишком агрессивными, как я уже сказал, вы можете затопить сеть и повлиять на системы, которые иначе вы бы не затронули). Я действительно рекомендовал бы поискать подходящий инструмент сетевой оркестровки, такой как Ansible ( https://www.ansible.com/), поскольку это не только решит ваши проблемы параллелизма (Ansible автоматически выполняет пакетирование, как я уже упоминал выше), но и предоставит вам множество других полезных функций (например, идемпотентное выполнение задач, хорошие отчеты о состоянии и встроенная интеграция с очень большое количество других инструментов).


Существуют способы запуска ограниченного числа фоновых задач (с использованием bash, perl, python и др.), Отслеживания выполнения задач и выполнения большего количества задач по мере выполнения предыдущих задач. Простым подходом будет сбор пакетов задач, представленных файлами в подкаталогах, и обработка пакета за раз. Есть и другие способы ...
— ЧакКоттрилл

Включает ли это также Unix-подобные системы? А что такое "GUN параллель"?
— Biswapriyo

2
@ChuckCottrill Да, действительно, есть и другие способы сделать это. Однако, учитывая мой собственный опыт работы с подобными вещами, почти всегда лучше просто получить реальный инструмент оркестровки, чем пытаться развернуть свое собственное решение, особенно когда вы пройдете несколько десятков систем с точки зрения масштаба.
— Остин Хеммельгарн


3
@forest Да, вы можете использовать rlimits для предотвращения сбоев системы, но получить их правильно в случае, подобном этому, нелегко (вам нужно заранее знать, какие требования к ресурсам для выполнения задач) и не защищать остальной части сети от любого воздействия, которое могут оказать эти задания (что, возможно, является гораздо более серьезной проблемой, чем сбой локальной системы).
— Остин Хеммельгарн

12

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

Могу ли я предложить вам использовать GNU параллельно ( https://www.gnu.org/software/parallel/ ) или что-то подобное для достижения этой цели? Это даст вам ряд преимуществ по отношению к фоновой работе:

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

Посмотрите здесь для быстрого начала: https://www.gnu.org/software/parallel/parallel_tutorial.html#A-single-input-source


1
Интересный! Я посмотрю на это. Знаете ли вы, если попытка такого рода операций (без помощи Parallel) может привести к сбою гипервизора?
— KuboMD

2
@KuboMD, если вы можете разбить гипервизор чем-то таким обыденным, это ошибка в гипервизоре :)
— hobbs

Кроме того, веб-серверы часто используют многопоточность или обработку на основе событий (пример: gunicorn.org )
— ChuckCottrill

10

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

ls ~/sagLogs/ | parallel --delay 0.5 --memfree 1G -j0 --joblog my.log --retries 10 foo {}

Это будет работать fooдля каждого файла в ~/sagLogs. Он запускает задание каждые 0,5 секунды, он будет запускать как можно больше заданий параллельно, пока свободна ОЗУ 1 ГБ, но будет соблюдать ограничения в вашей системе (например, количество файлов и процессов). Как правило, это означает, что вы будете выполнять 250 заданий параллельно, если не отрегулировали количество разрешенных открытых файлов. Если вы отрегулируете количество открытых файлов, у вас не должно возникнуть проблем при параллельном запуске 32000 - если у вас достаточно памяти.

Если задание не выполнено (то есть возвращается с кодом ошибки), оно будет повторено 10 раз.

my.log скажет вам, если задание выполнено успешно (после повторных попыток) или нет.


Это выглядит очень многообещающе, спасибо.
— KuboMD

Провел простое испытание cat ~/sagLogs/* >> ~/woah | parallelи святой моли, который был быстр. 1,054,552 строк в мгновение ока.
— KuboMD

3
Команда, которую вы дали, имеет двойное перенаправление, поэтому я не думаю, что она делает то, что вы намеревались сделать. На GNU Parallel накладные расходы составляют 10 мс на одно задание, поэтому выполнение 1M заданий занимает порядка 3 часов.
— Оле Танге

1
Это вообще не применимо, если все, что вы хотите сделать, это просто объединить файлы.
— Оле Танге

1
@KuboMD - тривиальный цикл занятости процессора, с которым awk 'BEGIN{for(i=rand()*10000000; i<100000000;i++){}}' можно поиграть. Или попробуйте выполнить задачу, например, sleep 10увидеть, как она работает nв полете, не тратя много времени на процессор. например, time parallel sleep ::: {100..1}бегать спит от 100 до 1 секунды.
— Питер Кордес

1

Что произойдет, если я начну слишком много фоновых заданий?

система станет медленной и не отвечает, худший случай настолько не отвечает, что было бы лучше просто нажать кнопку питания и выполнить полную перезагрузку ... это будет запускать что-то от имени пользователя root, где у него была привилегия уйти с этим. Если ваш Баш скрипт работает в обычных привилегиях пользователя, то первое , что приходит на ум, /etc/security/limits.confи /etc/systemd/system.confи все переменные в нем [идеале говоря] предотвратить пользователь (ей) от перегрузки системы.

  • процессор = xeon E5649, то есть 12- ядерный процессор; Таким образом, у вас есть 12 ядер для 12 процессов, выполняемых одновременно, каждое из которых использует одно из двенадцати ядер на 100%. Если вы запустите 24 процесса, то каждый из них будет работать с 50% -ной загрузкой на каждом из двенадцати ядер, 700 процессов = 1,7%, но это компьютер, если все будет выполнено правильно за приемлемое количество времени, тогда это = успех; Быть эффективным не всегда актуально.

    1. Могут ли все 700 экземпляров работать одновременно? Конечно, 700 не так много; например, мой /etc/security/limits.conf по maxprocумолчанию равен 4 135 275

    2. Как далеко я могу пройти, пока мой сервер не достигнет своего предела? Я уверен, что намного дальше, чем 700.

    3. Ограничения ... что произойдет, если скрипт будет запущен под учетной записью пользователя [и, в целом, root, а также в limits.confзначительной степени относится ко всем], - это то, что скрипт просто завершится после попытки выполнить foo &700 раз; тогда вы ожидаете увидеть 700 процессов foo, каждый с разным pid, но вы можете увидеть только 456 (выбор случайного числа), а остальные 244 никогда не запускались, потому что они были заблокированы каким-то ограничением безопасности или системным ограничением.

Вопрос на миллион долларов: сколько вы должны запустить одновременно?

участвуя в работе сети, и вы сказали, что каждый из них будет устанавливать соединение с telnet, догадываясь о том, что вы столкнетесь с сетевыми ограничениями и накладными расходами, прежде чем начнете использовать ограничения ЦП и ОЗУ. Но я не знаю, что конкретно вы делаете, что, скорее всего, произойдет, если вы можете запустить все 700 одновременно, но все будет автоматически блокироваться, пока предыдущие процессы и сетевые подключения не завершатся и не закроются в зависимости от различных системных ограничений, или что-то вроде Первые 500 начнутся, а остальные 200 - нет, потому что ограничения системы или ядра мешают. Но как бы ни бегали сразу, будет немного сладковатогоместо, чтобы сделать все как можно быстрее ... минимизируя накладные расходы и повышая эффективность. Будучи 12 ядрами (или 24, если у вас 2 процессора), начните с 12 (или 24) сразу, а затем увеличивайте число одновременных партий на 12 или 24, пока не увидите улучшения во время выполнения.

Подсказка: Google Max Telnet подключений и посмотреть, как это относится к вашей системе (ам). Также не забывайте о брандмауэрах. Также выполните быстрый расчет памяти, необходимой для каждого процесса x 700; убедитесь, что <доступно ОЗУ (около 50 ГБ в вашем случае), иначе система начнет использовать SWAP и в основном перестанет отвечать на запросы. Таким образом, запускайте 12, 24, N процессов одновременно и следите за свободным объемом ОЗУ, затем увеличивайте N, уже имея некоторые знания о том, что происходит.

По умолчанию RHEL ограничивает количество соединений telnet с одного хоста до 10 одновременных сеансов. Это функция безопасности ... установите значение 10, /etc/xinetd.conf, измените значение per_source.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.