PHP Parallel / Distributed Tool & MySQL & Как заблокировать функцию на нескольких серверах - PullRequest
0 голосов
/ 13 марта 2012

Я собирал инструменты PHP с бэкэндом MySQL.Используя multi-curl, я могу запускать десятки, а иногда и сотни каждого сценария одновременно на одном старом ПК (на котором теперь установлен последний рабочий стол Ubuntu).Каждая машина и каждая виртуальная машина на каждой машине способны запускать десятки одновременных экземпляров.

В результате я быстро исчерпал соединения MySQL.Когда я увеличил количество соединений в MySQL, я заморозил четырехъядерный компьютер, который я использовал для размещения сервера MySQL.С тех пор я перешел к схеме, в которой у меня есть БД, специально предназначенная для управления запросами других БД и использования заданий cron, которые выполняются часами, и я поддерживаю несколько открытых соединений на машину.На данный момент я все еще на стадии легкого тестирования, и я не пытался сделать сотни одновременных запросов, чтобы посмотреть, как сервер MySQL справляется с этим.

Вместо этого я столкнулся с другой проблемой, которую я 'Мы попробовали несколько решений для всех с примерно одинаковыми результатами.Проблема заключается в том, что дубликаты данных вводятся в БД, потому что у меня есть параллельные экземпляры инструмента, работающего на разных машинах.Например, я загружаю большой объем новых данных в свою БД, и для этих данных необходимо выполнить несколько задач, таких как привязка адреса электронной почты к профилю пользователя.Я предпочел, чтобы фоновый процесс cron обрабатывал это постепенно, и каждая машина делит это каждые 5 минут.Поскольку все они запускаются в одно и то же время, они все получают одни и те же данные электронной почты и фильтруют их, используя ту же логику, по которой адреса электронной почты имеют более высокий приоритет.Затем каждая машина начинает делать то, что должно быть сделано с электронными письмами, которые она выбрала.Поскольку все они запускаются в одно и то же время, они часто собирают одни и те же данные и пытаются выполнить одинаковые связи.Это вызывает исключение первичного ключа в таблице связей, но не некоторые другие.Поэтому я получаю дубликаты данных в некоторых таблицах и иногда неполные связи.

Я попытался рандомизировать данные SELECT, чтобы машины работали с разными наборами данных.Тем не менее, это, конечно, неоптимально в отношении того, что я хотел бы, чтобы инструмент выполнял, поэтому мне нужно чаще запускать инструмент, чтобы определенные задачи выполнялись в требуемые сроки.Я попытался создать флаг в БД, который обозначает, что 1 сервер активно использует данные, поэтому все остальные серверы должны подождать.Иногда это работает, но иногда 2 машины опрашивают этот флаг одновременно.Поскольку мы говорим о нескольких машинах, я не собираюсь работать.И из того, что я прочитал, блокировка таблицы в БД также не может быть хорошим решением.

Так что я пришел в StackOverflow за советом, а не продолжал бить себя головой о стену.

== Обновление ==

Gearman выглядел как отличное решение, поэтому я дал ему большие пальцы в качестве ответа.Однако мне так и не удалось заставить его работать с моей установкой PHP.Я попробовал несколько наборов предложений / инструкций онлайн, многие из которых даже не установили механизм.Насколько я могу судить, предложение использовать apt-get install gearman-server действительно установило gearman - то есть никаких ошибок не было, и gearmand запускался.Однако, когда я пытался использовать клиенты и работники gearman в сценариях, я получал ошибки, связанные с невозможностью найти эти классы.

После этого я добавил файл gearman.ini в правильный каталог.У него была 1 строка extension=gearman.so.Это привело к другой ошибке, когда PHP сказал мне, что не может найти gearman.so.Я попытался использовать sudo find / -name gearman.*, чтобы найти gearman.so, но безуспешно - он вернул файлы C, но не gearman.so.

В настоящее время я очень, очень, очень хотел бы реализовать gearman, но так как я не могу заставить его работать, я застрял в своем коде взлома и слэша для реализации моего распределенного набора инструментов. Мое «решение» на сегодняшний день - создать флаг, для которого установлено «OCCUPIED», когда 1 экземпляр инструмента делает что-то, что может вызвать проблемы с дублированием данных. Я создал 5 одинаковых флагов с постфиксами _1, _2, ..., чтобы 5 экземпляров могли работать одновременно. (Я использую _1, _2, ... для создания смещения в возвращаемых данных БД, чтобы никакие 2 экземпляра инструмента не работали с одним и тем же набором данных. Другими словами, если инструкция SELECT вернула бы более 100 строк, и я только работает по 10 одновременно, _1 работает по строкам 1-10, _2 работает по 11-20, ... Не идеально, но он должен позволять нескольким серверам работать с БД одновременно без создания дублирующих данных.)

Тайм-аут инструмента API БД, если он не видит результат в течение 30 секунд. Проблема в том, что при попытке получить эти состояния флага часто возникают тайм-ауты ...

1 Ответ

1 голос
/ 13 марта 2012

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

Взгляните на Gearman для примера

...