Мы запускаем мета-поисковую систему (сравнение цен), где каждый поиск порождает несколько поисковых запросов в реальном времени на различных веб-сайтах и представляет объединенные и отсортированные результаты поиска на нашем сайте.
Мы используем PHP / MySQL / Apache на сервере Linux Debian в довольно простой настройке, но фоновая обработка параллельного поиска на нескольких сайтах выполняется Tomcat и сервлетом Java. Однако из-за некоторых проблем с этой настройкой (Tomcat) я исследую новые подходы к фоновому поиску.
Один из способов, который выглядит многообещающим, также очень прост: на главной странице поиска каждый отдельный сценарий поиска запускается как PHP CLI с использованием exec ():
exec("nohup /usr/bin/php search.php '$params' &> /dev/null &");
Использование амперсанда в конце отправляет сценарии CLI PHP прямо в фоновый режим, и главная страница может продолжаться без ожидания. Для каждого поиска выполняется около 20 скриптов.
Кажется, он работает достаточно хорошо, но когда я запускаю стресс-тест с использованием Apache Benchmark с параллельными запросами, начинают появляться проблемы. Что происходит, так это то, что MySQL сообщает об этой ошибке:
Не удается подключиться к локальному серверу MySQL через сокет '/var/run/mysqld/mysqld.sock' (11)
Это похоже на вариант «Слишком много подключений», но это не помогает повысить ограничения в my.cnf. Но что меня действительно озадачивает, так это то, что эти ошибки присутствуют, даже если я вызываю небольшой фиктивный скрипт, который ничего не делает и, конечно же, не обращается к MySQL. Итак, похоже, что простой запуск PHP CLI загружает MySQL, даже если он не используется.
Во время моих тестов выполняется не более 700 экземпляров PHP, а загрузка процессора и памяти ниже, чем при использовании Tomcat для вызова сценариев PHP, поэтому с этой точки зрения это выглядит выполнимым.
Есть ли у кого-нибудь представление о проблеме MySQL? И, конечно же, я открыт для новых идей о том, как справляться с фоновыми задачами!
С уважением, Мартин
Я бы сказал, что создание рабочих мест слишком просто и, безусловно, может привести к нехватке ресурсов.
Чтобы избежать этого, я бы использовал какую-либо форму очереди - либо через таблицу базы данных, в которой перечислено, что требуется, и затем регулярно проверяется, либо систему очереди заданий, что-то вроде Gearman или Beanstalkd. Вы помещаете в очередь сообщение - то, что вы хотите найти - и фоновую задачу, которая уже выполняется, которая выбирает задания по мере их поступления, и она имеет возможность, выполняет соответствующие задачи и передает информацию обратно, либо через БД, либо через какую-нибудь систему в памяти, например Memcached. Интерфейсная система может обновиться (или использовать Ajax), чтобы перезвонить и посмотреть, была ли найдена какая-либо информация, отображая ее при необходимости.
Это разделяет переднюю и заднюю части и избавляет от необходимости закрывать все соединения, открытые вашим скриптом (см. Предупреждение на exec)
Мартин,
Я определенно не специалист в этом вопросе, но на ум приходит пара вещей.
Я думаю, что php загружает поддержку mysql, независимо от того, используете ли вы ее в своем скрипте, но он не должен запускать соединение, если вы не используете Постоянные соединенияЯ бы не подумал, что скрипты cli унаследуют соединение mysql от дочернего Apache, но, судя по всему, это должно быть основано на вашем тестировании.
Вы также можете столкнуться с слишком много файлов ограничение на mysql. Также есть ссылка на то, что нехватка ОЗУ / ресурсов является причиной ошибки mysql. Вы сказали, что он показывает меньшую нагрузку, чем ваша старая установка, но может ли это быть слишком много? Когда эти сценарии запущены, есть ли возможность установить соединение с сервером mysql с помощью графического интерфейса пользователя (администратор mysql)? Если это так, вы потенциально можете увидеть, что у него закончились ресурсы ...
С точки зрения базы данных было бы более эффективно, если бы ваши 20 поисковых запросов выполнялись только в одном скрипте, а не порождали несколько скриптов. Это позволит вам использовать одно соединение mysql для всех 20 поисков и соответственно увеличит емкость вашего соединения. Другими словами, Web Script ---- порождает -----> CLI-сценарий в фоновом режиме, который проходит через все ваши поиски.
Незнание вашего кода или того, что вы делаете, это всего лишь предположение как исправление кода.
Удачи
Извините за задержку с ответом. Я заболел гриппом.
Спасибо за ваш отзыв. Есть над чем подумать!
Я провел еще несколько экспериментов с вызовом сценариев с помощью wget вместо сценариев CLI, и, кроме того, Lighttpd обслуживает эти специальные сценарии поиска на порту 81 - чтобы снять нагрузку с основного сервера Apache.
Пока это выглядит многообещающе, но я, возможно, спрошу еще раз, когда проведу еще немного тестов.
Изменить: я оригинальный постер, не знаю, почему он выглядит как чужой пост. Возможно что-то с моим OpenID ...