Что является узким местом, когда это не память, процессор или ввод-вывод? - PullRequest
1 голос
/ 09 ноября 2011

У меня есть класс PHP, который выбирает данные о файле из базы данных MySQL, обрабатывает эти данные в PHP и затем выводит окончательные данные в командную строку. Затем он переходит к следующему файлу внутри цикла foreach. (позже я вставлю эти данные в другую таблицу ... но это сейчас не важно)

Я хочу сделать обработку максимально быстрой.

Когда я запускаю скрипт и наблюдаю за своей системой, используя top или iostat:

  • мои процессоры не менее 65% простаивают (4-ядерный экземпляр EC2)
    • скрипт PHP занимает около 45%
    • MySQL сидит примерно на 8%
  • мое использование памяти никогда не превышает ~ 1,5 ГБ (8 ГБ общей оперативной памяти)
  • очень мало дискового ввода-вывода

Какие еще узкие места могут помешать этому процессу работать быстрее и использовать доступные процессор и память?

РЕДАКТИРОВАТЬ 1:

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

Я наблюдал за дисковым вводом / выводом, используя iostat -x 1, и очень мало.

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

Ответы [ 6 ]

4 голосов
/ 09 ноября 2011

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

Пример: если бы PHP был единственным, работающим на этом компьютере, он был привязан к одному ядру на «задание» и выполнялся только один запрос за раз, я бы полностью ожидал, что загрузка процессора составит около 25 %, несмотря на то, что он уже идет так быстро, как только может.

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

По моему мнению, вам действительно следует беспокоиться о проблеме производительности, только если это фактическая проблема (например, неспособность идти в ногу с входящими запросами). Оптимизация только потому, что вы хотите использовать больше ресурсов процессора и / или памяти, кажется, смотрит на это неправильно. Я бы просто запустил его как можно быстрее , не беспокоясь о .


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

Другими словами, если обработка одного файла независима, вы можете просто запустить два или три PHP-процесса и заставить их обрабатывать по одному файлу каждый. Это с большей вероятностью заставит их работать на разных ядрах.

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

Если не вдаваться в подробности, варианты, которые я могу предоставить, будут в основном общими.

1 голос
/ 09 ноября 2011

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

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

Думайте о любом компьютере и программном обеспечении так же, как в этом ретрансляторе, за исключением шкалы наносекунд, а не секунд.Когда компьютер выполняет вычисления в программе, он выполняет инструкции одну за другой.Назовите это "X".Когда программа хочет прочитать или записать некоторые биты на внешнее оборудование, она должна запросить это оборудование для запуска, а затем она должна найти способ убить время, пока результат не будет готов.Назовите это "у".Это может быть простой цикл или запуск другого «потока» и т. Д.

Таким образом, выполнение программы выглядит следующим образом:
XXXXXyyyyyyyXXXXXXXXyyyyyyy
Если в нем больше «y», чем »X, мы склонны называть это «I / O bound».Если нет, то мы могли бы назвать это «вычислимым»В любом случае, это всего лишь пропорция времени, потраченного.

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

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

Теперь, в пределах одногонить, если вы случайно выберете "X" или "y", как вы сможете определить, можете ли вы от него избавиться?Узнайте, какова его цель!Это «X» или «y» представляет момент в последовательности выполнения программы, и если вы посмотрите на состояние программы в то время и посмотрите на исходный код, вы сможете выяснить, почему этот моменттратится.Сделайте это несколько раз.Как только вы видите, что два момента времени имеют похожую, но не совсем необходимую цель, вероятно, их становится намного больше, и вы нашли то, от чего вы можете избавиться.Если вы это сделаете, программа больше не будет тратить это время.

Это основная идея этого метода настройки производительности. Вот пример, где этот метод использовался в течение нескольких итераций для удаления более 97% времени, затрачиваемого на программу.Не все программы настолько далеки от оптимальных.(Некоторые намного дальше.) Многим программам просто нужно выполнить определенное количество «X» или «Y», и нет никакого способа обойти это.Тем не менее, часто очень удивительно, сколько места вы можете найти для ускорения в другом, совершенно хорошем коде - при условии - вы забываете о «узких местах» и ищите шаги, которые он делает со временем, которые можно было бы удалить или сделать лучше.

Это просто.

0 голосов
/ 27 апреля 2015

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

У меня была та же проблема: параллельный запуск нескольких процессов, все с использованием MySQL.Машина работала медленно, без видимых узких мест: процессора, памяти и диска.

Оказалось, что наиболее вероятной причиной моих проблем было то, что внутренние потоки MySQL большую часть времени висели на одном семафоре.Переключение с vanilla MySQL 5.5 на MariaDB 10.0 решило проблему.

Кроме того, чтобы моя машина всегда работала на полную мощность, а не была залита, я создал скрипт Perl raspawn.pl (на GitHub).

Вы можете прочитать полную печальную историю здесь .

0 голосов
/ 20 ноября 2014

Извините, что воскресил старую ветку, но подумал, что это может кому-то помочь.

У меня была похожая проблема, и она имела отношение к сценарию командной строки, который выдавал многочисленные предупреждения «Уведомление». Это как-то привело к тому, что он работал медленно и использовал менее 10% процессора. Такое поведение проявлялось только при переходе с MacOS X на Ubuntu, так как по умолчанию в OSX, по-видимому, подавляются потери. После того, как я исправил нарушающий код, он стал работать намного лучше, и процессы использовали примерно 100% процессоров.

0 голосов
/ 09 ноября 2011

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

100% использование одного ядра приведет к «25% загрузке ЦП», если остальные три ядра простаивают.

Ваши цифры соответствуют сценарию php, работающему на 100% на одном ядре, с использованием от 5 до 10% на остальных трех ядрах.

0 голосов
/ 09 ноября 2011

Я подозреваю, что вы проводите большую часть своего времени, общаясь с MySQL и читая файлы. Как вы определяете, что IO очень мало? Связь с MySQL будет осуществляться по сети, что очень медленно по сравнению с прямым доступом к памяти. То же самое с чтением файлов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...