Как Вы хорошо используете многоядерные центральные процессоры в своих приложениях PHP/MySQL?

Я поддерживаю сделанное на заказ подобное CMS приложение.

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

  1. Запросы MySQL.
  2. Парсинг содержимого HTML.
  3. Поисковое индексное обновление.

Категория 1 включает обновления различных таблиц MySQL, касающихся содержания документа.

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

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

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

Машина, которая размещает это приложение, имеет двойные четырехъядерные процессоры Xeon (в общей сложности 8 ядер). Однако каждый раз, когда документ отправляет, весь код PHP, который выполняется, ограничивается к единственному процессу, работающему на одном из ядер.

Мой вопрос:

Какие схемы, если таковые имеются, Вы раньше разделяли Ваше веб-приложение PHP/MySQL, обрабатывающее загрузку среди нескольких ядер процессора? Мое идеальное решение в основном породило бы несколько процессов, позволить им выполниться параллельно на нескольких ядрах и затем блоке, пока все процессы не сделаны.

Связанный вопрос:

Какова Ваша любимая производительность PHP профильный инструмент?

32
задан jkndrkn 15 February 2010 в 16:30
поделиться

2 ответа

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

К сожалению, с этим мало что можно поделать: так работает PHP.


Тем не менее, вот пара мыслей:

  • Во-первых, на вашем сервере, вероятно, будет более 1 пользователя одновременно, что означает, что вы будете обслуживать несколько страниц одновременно, что, в свою очередь, означает, что у вас будет несколько процессов PHP и SQL-запросов, выполняемых одновременно... что означает, что будет использоваться несколько ядер вашего сервера.
    • Каждый процесс PHP будет работать на одном ядре, отвечая на запрос одного пользователя, но параллельно работает несколько подпроцессов Apache (по одному на каждый запрос, до нескольких десятков или сотен, в зависимости от вашей конфигурации)
    • Сервер MySQL является многопоточным, что означает, что он может использовать несколько отдельных ядер для ответа на несколько одновременных запросов - даже если каждый запрос не может быть обслужен более чем одним ядром.

Так что, фактически, 8 ядер вашего сервера в конечном итоге будут использованы ;-)


И, если вы думаете, что ваши страницы генерируются слишком долго, возможное решение - разделить ваши вычисления на две группы:

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

Для ситуаций, описанных во втором пункте, когда вам не нужно делать эти вещи немедленно... Ну, просто не делайте их немедленно ;-)
Решение, которое я часто использую - это механизм очередей:

  • Веб-приложение хранит вещи в "todo-list"
  • И этот "todo-list" снимается с очереди некоторыми партиями, которые запускаются часто через cronjob

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

37
ответ дан 27 November 2019 в 19:54
поделиться

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

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

Мертвая ссылка: Стратегии многопоточности в PHP

2
ответ дан 27 November 2019 в 19:54
поделиться
Другие вопросы по тегам:

Похожие вопросы: