Анатомия распределенной системы в PHP - PullRequest
27 голосов
/ 04 октября 2009

У меня есть проблема, из-за которой мне трудно найти идеальное решение, и, чтобы лучше объяснить это, я собираюсь изложить свой сценарий здесь.

У меня есть сервер, который будет принимать заказы от нескольких клиентов. Каждый клиент будет представить набор повторяющихся задач, которые должно быть выполнено в некоторых указанных интервалы, например: клиент A отправляет задачу АА, который должен выполняться каждый минута между 2009-12-31 и 2010-12-31 ; так что если моя математика верна это около 525 600 операций в год, учитывая больше клиентов и задач было бы невозможно позволить серверу обрабатывать все эти задачи , поэтому я придумал идею рабочего машины. Сервер будет разрабатываться на PHP.

рабочие машины просто обычные дешевые компьютеров на базе Windows , которые я хозяин у меня дома или на работе, у каждого работника будет свой Интернет-соединение ( с динамическими IP-адресами ) и ИБП, чтобы избежать перебоев в подаче электроэнергии. каждый работник также будет запрашивать сервер каждый 30 секунд или около того через вызовы веб-службы, получить следующую ожидающую работу и обработать ее. Как только работа будет завершена, работник отправить вывод на сервер и запросить новая работа и так далее до бесконечности. Если есть необходимость масштабировать систему I следует просто настроить нового работника и все должно работать без проблем. Рабочий клиент будет развиваться в PHP или Python.

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

Теперь вот где начинается сложная часть:

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

У меня есть некоторые сомнения относительно общего дизайна базы данных и какие технологии использовать.

Первоначально я думал об использовании нескольких SQLite баз данных и , объединяющих их все на сервере, но я не могу понять, как я буду группировать по клиентам для генерации отчетов о заданиях .

Я никогда не работал ни с одной из следующих технологий: memcached , CouchDB , Hadoop и тому подобное, но я хотел бы знать, если какой-либо из них подходит для моей проблемы, и если да, то, что вы рекомендуете новичку, это «распределенные вычисления» (или это параллель?), как я. Имейте в виду, что рабочие имеют динамические IP-адреса.

Как я уже говорил ранее, у меня также возникают проблемы с общим дизайном базы данных, отчасти потому, что я до сих пор не выбрал какую-либо конкретную R (D) СУБД, но есть одна проблема, которая у меня есть, и я думаю, что она не зависит от СУБД Выбор связан с системой очередей ... Если я произвожу предварительный расчет всех абсолютных временных отметок для конкретной работы и получу большой набор временных отметок , выполните и отметьте их как завершенные в порядке возрастания или у меня должна быть более умная система типа ", когда модуль отметки времени 60 == 0 -> выполнить ". Проблема с этой «умной» системой заключается в том, что некоторые задания не будут выполняться в порядке , поскольку они должны быть, потому что некоторые рабочие могут ждать, ничего не делая, в то время как другие перегружены. Что вы предлагаете?

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

Спасибо за ваш вклад!

@ timdev:

  1. На входе будет очень маленькая строка в кодировке JSON, на выходе также будет строка в кодировке JSON, но немного больше (порядка 1-5 КБ).
  2. Вывод будет рассчитываться с использованием нескольких доступных ресурсов из Интернета, поэтому основным узким местом, вероятно, будет пропускная способность. Запись в базу данных также может быть одна - в зависимости от СУБД R (D).

Ответы [ 7 ]

15 голосов
/ 05 октября 2009

Похоже, вы находитесь на грани воссоздания Gearman . Вот введение для Gearman:

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

Вы можете написать как свой клиент, так и рабочий код на PHP.


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

Сотрудники Sun / MySQL Эрик Дэй и Брайан Акер в июле 2009 года на OSCON дали учебное пособие для Gearman для OSCman, но на их слайдах упоминаются только пакеты Linux.

Вот ссылка на проект Perl CPAN Testers, который указывает, что Gearman-Server может быть собран на Win32 с использованием компилятора Microsoft C (cl.exe), и он проходит тесты: http://www.nntp.perl.org/group/perl.cpan.testers/2009/10/msg5521569.html Но я бы думаю, вам нужно скачать исходный код и собрать его самостоятельно.

4 голосов
/ 14 октября 2009

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

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

Разработка индивидуального решения может сработать, но преимущества gearman, особенно постоянная очередь, мне кажется, что это может быть лучшим решением для вас на данный момент. Я не знаю о бинарном Windows для gearman, но я думаю, что это должно быть возможно.

3 голосов
/ 17 октября 2009

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

На главном сервере Я бы установил MySQL (Percona InnoDB версия стабильна и быстра ) в репликации мастер-мастер, поэтому у вас не будет ни единой точки отказа.На главном сервере будет размещаться API, который рабочие будут использовать каждые N секунд.Мастер проверит, есть ли доступная работа, если это так, он должен отметить, что работа была назначена работнику X, и вернуть соответствующий ввод работнику (все это через HTTP).Кроме того, здесь вы можете хранить все файлы сценариев рабочих.

На рабочих я настоятельно рекомендую вам установить дистрибутив Linux.В Linux проще устанавливать запланированные задачи, и в целом я думаю, что это больше подходит для работы.С Linux вы даже можете создать live cd или iso образ с идеально настроенным рабочим и быстро и легко установить его на все нужные вам машины.Затем настройте задание cron, которое будет RSync с главным сервером для обновления / изменения сценариев.Таким образом, вы измените файлы только в одном месте (главный сервер), и все рабочие получат обновления.

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

Рабочая задача довольно проста: запросите работу у API, сделайте это, отошлите результат через API.Промыть и повторить: -)

3 голосов
/ 15 октября 2009

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

Рассмотрим Postgres, который имеет промышленный параллелизм и управление блокировками и может очень хорошо обрабатывать несколько одновременных транзакций.

Также это звучит как работа для очередей! Если бы вы были в мире Java, я бы порекомендовал архитектуру на основе JMS для вашего решения. Есть проект dropr, который делает что-то подобное в php, но все это довольно ново, поэтому он может не подойти для вашего проекта.

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

3 голосов
/ 05 октября 2009

Более простым решением было бы иметь одну базу данных с несколькими подключенными php-узлами. Если вы используете правильную СУБД (MSql + InnoDB подойдет), вы можете использовать одну таблицу в качестве очереди. Затем каждый работник будет извлекать задачи для выполнения и записывать их обратно в базу данных после завершения, используя транзакции и блокировки для синхронизации. Это немного зависит от размера входных / выходных данных. Если оно большое, возможно, это не лучшая схема.

2 голосов
/ 19 октября 2009

Вместо того, чтобы заново изобретать колесо очереди через SQL, вы можете использовать систему сообщений, такую ​​как RabbitMQ или ActiveMQ , в качестве ядра вашей системы. Каждая из этих систем обеспечивает протокол AMQP и имеет очереди на жестком диске. На сервере у вас есть одно приложение, которое помещает новые задания в очередь «работника» в соответствии с вашим расписанием, а другое - записывает результаты из очереди «результата» в базу данных (или воздействует на нее другим способом).

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

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

1 голос
/ 04 октября 2009

Я думаю, что вы идете в правильном направлении с главным дистрибьютором работы и рабочими. Я хотел бы, чтобы они общались через HTTP.

Я бы выбрал C, C ++ или Java в качестве клиентов, поскольку у них есть возможности для запуска скриптов (execvp в C, System.Desktop.something в Java). Задания могут быть просто именем сценария и аргументами этого сценария. Вы можете попросить клиентов вернуть статус на рабочих местах. Если задания не пройдены, вы можете повторить их. Вы можете опрашивать клиентов на предмет заданий каждую минуту (или каждые x секунд и заставлять сервер сортировать задания)

PHP будет работать на сервере.

MySQL отлично подойдет для базы данных. Я бы просто сделал две метки времени: начало и конец. На сервере я бы искал WHEN SECONDS == 0

...