Мне необходимо написать систему для распределенных вычислений.
Кое-что я уже сделал.
Вкратце архитектура такая: есть центральный узел — Dispatcher, который распределяет задания,
RemoteAgent, который решает задания и Director который задания выдает.
Сейчас все это реализовано на Java и RMI. А моя проблема состоит в следующем я не знаю как правильно/лучше организовать вызовы в системе. У меня сейчас так: Director ищет реестры RMI по всей сети, находит и обращается к Dispatcher'у и оставляет там ссылку на себя. Диспетчер на этой ссылке вызывает метод getTask и получает описание задачи в XML. Удаленные агенты тоже ищут реестр RMI находят диспетчера и оставляют у него ссылки на себя. Диспетчер имея список удаленных агентов раздает им задачи методом setTask. После того как удаленные агенты решают задачи они вызывают на диспетчере(ссылка на него передается в setTask) метод complete(ссылка на уд. агента). Диспетчер после этого вызывает на удаленном агенте метод getTask и получает XML с решением задачи. Затем он передает решение Director'у методом director.setTask(String xml).
На диспетчере запущены потоки определения живых агентов и директоров
Что мне не нравится в существующей схеме:
Много обратных вызовов — проблема потери соединения, падения агентов.
Удаленные агенты могут очень много времени решать задачу => ссылка на диспетчер может стать не действительной
Директор не обязательно должен быть всегда запущен.
Так же я хотел бы переделать удаленног агента на С++ или С# — это нужно для того чтобы они запускались как сервисы на компьютере пользоваиеля, вели бы мониторинг системы(загруженность, память и т.д.). Отсюда еще один вопрос как организовать общение CORBA или WS (c CORBA немного знаком с WS — нет ).
Сейчас каждый удаленный агент и директор является так же и сервером RMI, хотелось бы этого избежать.
Пожалуйста подскажите более правильное решение этой задачи или плохие места в уже реализованном решении.
Не по сути вопроса.
Если вы это пишите не в учебных целях, то процентов 80 вероятности (даже не глядя на ваш код) это будет работать медленнее чем работало бы на одной машине.
Здравствуйте, gamial, Вы писали:
G>Здравствуйте, kudinov.
G>Не по сути вопроса. G>Если вы это пишите не в учебных целях, то процентов 80 вероятности (даже не глядя на ваш код) это будет работать медленнее чем работало бы на одной машине.
Нет это уже совершенно точно работает быстрее чем на одной машине ( На узлах удаленных агентов работает Matlab, а се месте решает задачу стат. анализа стохастических систем с нестационарными коэффициентами)
CORBA даст вам большую скорость, чем WEB сервисы, если это актуально — то используете её. Мы в свое время разрабатывали систему моделирования авиационного двигателя, так там вычислители были на C/C++ под Linux и Windows, а система управления и визуализация была на основе Java Eclipse Rich Client, для взаимосвязи использовалась CORBA. Все работало очень шустренко.
K>Так же я хотел бы переделать удаленног агента на С++ или С# — это нужно для того чтобы они запускались как сервисы на компьютере пользоваиеля, вели бы мониторинг системы(загруженность, память и т.д.). Отсюда еще один вопрос как организовать общение CORBA или WS (c CORBA немного знаком с WS — нет ).
K>Сейчас каждый удаленный агент и директор является так же и сервером RMI, хотелось бы этого избежать.
K>Пожалуйста подскажите более правильное решение этой задачи или плохие места в уже реализованном решении.
K>Спасибо.
Здравствуйте, kudinov, Вы писали:
K>Здравствуйте.
K>Мне необходимо написать систему для распределенных вычислений. K>Кое-что я уже сделал. K>Вкратце архитектура такая: есть центральный узел — Dispatcher, который распределяет задания, K>RemoteAgent, который решает задания и Director который задания выдает. K>Сейчас все это реализовано на Java и RMI. А моя проблема состоит в следующем я не знаю как правильно/лучше организовать вызовы в системе. У меня сейчас так: Director ищет реестры RMI по всей сети, находит и обращается к Dispatcher'у и оставляет там ссылку на себя. Диспетчер на этой ссылке вызывает метод getTask и получает описание задачи в XML. Удаленные агенты тоже ищут реестр RMI находят диспетчера и оставляют у него ссылки на себя. Диспетчер имея список удаленных агентов раздает им задачи методом setTask. После того как удаленные агенты решают задачи они вызывают на диспетчере(ссылка на него передается в setTask) метод complete(ссылка на уд. агента). Диспетчер после этого вызывает на удаленном агенте метод getTask и получает XML с решением задачи. Затем он передает решение Director'у методом director.setTask(String xml). K>На диспетчере запущены потоки определения живых агентов и директоров K>Что мне не нравится в существующей схеме: K> Много обратных вызовов — проблема потери соединения, падения агентов. K> Удаленные агенты могут очень много времени решать задачу => ссылка на диспетчер может стать не действительной K> Директор не обязательно должен быть всегда запущен.
<...> K>Сейчас каждый удаленный агент и директор является так же и сервером RMI, хотелось бы этого избежать.
Беда RMI — это затяжные синхронные вызовы (а по-другому не получится): приходится изобретать символические ссылки, не привязанные к системе, но привязанные к конкретному агенту. Если что-то оборвётся или отвалится — восстанавливайся сам, как сможешь.
Моё решение для Вашего случая: EJB, может быть Stateless Session Bean's, пулы бинов-агентов, которые представляют удалённые задачи клиентов (задачи исполняются на клиентах, агенты служат их представителями на сервере). Но скорее всего подойдёт парадигма Message-Driven Bean's: http://www.jboss.ru/docs/JBoss-2001-06-28/ch07s03.html
— система, основанная на очередях сообщений и асинхронных вызовах.
Здравствуйте, arts80, Вы писали:
A>CORBA даст вам большую скорость, чем WEB сервисы, если это актуально — то используете её. Мы в свое время разрабатывали систему моделирования авиационного двигателя, так там вычислители были на C/C++ под Linux и Windows, а система управления и визуализация была на основе Java Eclipse Rich Client, для взаимосвязи использовалась CORBA. Все работало очень шустренко.
Да я тоже склоняюсь к CORBA. У меня еще есть вопросы по архитектуре — точнее даже по вызовам в системе.
Сейчас основные мысли такие:
1). Общение программы, выдающей задачи с диспетчером.
1-й вызов проверка на уже решенные задачи (для данного пользователя)
2-й вызов просьба решить задачу
Вот здесь мысли расходятся: Должен ли клиент передавать описание задачи диспетчеру или же диспетчер сам должен забирать его у него. То есть вопрос реализовывать callback или нет. Или же должен ли клиент опрашивать диспетчера о решении задачи. Или все таки callback ?
2). Общение программы удаленного агента с диспетчером.
1-й вызов регистрация на диспетчере
2-й вызов передача нерешенных задач (Вопрос: или их забирает диспетчер или их передает удаленный агент)
Опять развилка — удаленный агент должен опрашивать диспетчера или диспетчер используя обратный вызов передает задачи удаленному агенту.
Напишите пожалуйста ваши мысли по этому поводу или может быть готовые примеры реализации.
Здравствуйте, iZEN, Вы писали:
ZEN>Беда RMI — это затяжные синхронные вызовы (а по-другому не получится): приходится изобретать символические ссылки, не привязанные к системе, но привязанные к конкретному агенту. Если что-то оборвётся или отвалится — восстанавливайся сам, как сможешь.
ZEN>Моё решение для Вашего случая: EJB, может быть Stateless Session Bean's, пулы бинов-агентов, которые представляют удалённые задачи клиентов (задачи исполняются на клиентах, агенты служат их представителями на сервере). Но скорее всего подойдёт парадигма Message-Driven Bean's: ZEN>http://www.jboss.ru/docs/JBoss-2001-06-28/ch07s03.html ZEN>- система, основанная на очередях сообщений и асинхронных вызовах.
В принципе сейчас архитектура похожая как раз используются прокси агентов на сервере. Использовать EJB я пока не хочу — слишком тяжеловесно. Может быть TOMCAT и Hibernate потом
1) По поводу общения — у нас задача передаеться не вычислителю, а программе(ЗАГРУЗЧИК) которая порождает вычислители. То есть на удаленном компьютере запускаеться программа, готовая получить проект для вычесления. После получения проекта она запускает собственно вычислитель, вычислитель регистрируеться в сервере CORBA имен и собственно начинает вычисления. Все взаимодействие с ним производиться по зарегисрированному имени. А программа ЗАГРУЗЧИК сразу же готова принять следующий проект. У нас нет понятия решенности задачи, так как программа GUI по управлению выполнением задачи дергает вычислителей раз 50 в секунду, такова специфика задачи.
2) У нас есть аналог диспетчера в вашем понимании, именно он забирает готовый проект из хранилища проектов и передает их ЗАГРУЗЧИКАМ, все загрузчики обязаны при старте регистрироваться в диспетчере, для этого они используют сервер имен CORBA, а именно генерируют уникальное имя и регистрируютсья под ним в сервере имен, а затем передают это имя диспетчеру.
По поводу вопросов(ИМХО):
1) Клиент сам должен передавать задачи диспетчеру, если диспетчер не способен выполнить задачу немедленно, то он сохраняет её в своем хранилище. При передачи задачи клиент передает и свое имя в сервере имен CORBA и идентификатор задачи, этот идентификатор и дергает агент при выполнении задачи, тем самым говоря клиенту что задача с таким то ID выполнена.
2)
— при старте агент регистрируеться в диспетчере — у нас также сделано, по моему довольно удобная схема.
— диспетчер передает задания агенту, а лучше не агенту, а ЗАГРУЗЧИКУ, при это ЗАГРУЗЧИК может отказатся взять задачу на выполнение если ресурсов осталось мало.
K>Да я тоже склоняюсь к CORBA. У меня еще есть вопросы по архитектуре — точнее даже по вызовам в системе.
Для C++ используем OmniORB, а для JAVA стандартную реализацию.
OmniORB есть как под Linux, так и под WINDOWS
K>Скажите если не секрет ,какой реализацией CORBA вы пользуетесь ?
Интересно, что все решения крутятся вокруг одного и того же Хотя конечно задачи и сильно разнятся.
В нашем случае система распределения заданий эволюционировала в выбор поставщиков (в ваших терминах "загрузчик", "решатель") на конкурсной основе.
В качестве основы использовался COSNotification. Все "поставщики" (решатели) регистрировались на канале. Клиент пускал заявку в канал получал предложения от доступных поставщиков и выбирал наиболее свободный и адекватный. В ответе поставщика была прямая объектная ссылка, поэтому все далее делалось напрямую между клиентом и поставщиком.
Плюсом такого решения стало:
1. Клиент не вел реестр поставщиков — это берет на себя канал notification
2. Асинхронные вызовы
3. Все элементы системы подписывались только на те сообщения, которые могли удовлетворить. Довольно сильно упрощает жизнь.
Для реализации использовалось TAO на разных платформах.
Здравствуйте, epflorov, Вы писали:
E>Интересно, что все решения крутятся вокруг одного и того же Хотя конечно задачи и сильно разнятся.
E>В нашем случае система распределения заданий эволюционировала в выбор поставщиков (в ваших терминах "загрузчик", "решатель") на конкурсной основе.
E>В качестве основы использовался COSNotification. Все "поставщики" (решатели) регистрировались на канале. Клиент пускал заявку в канал получал предложения от доступных поставщиков и выбирал наиболее свободный и адекватный. В ответе поставщика была прямая объектная ссылка, поэтому все далее делалось напрямую между клиентом и поставщиком.
E>Плюсом такого решения стало: E>1. Клиент не вел реестр поставщиков — это берет на себя канал notification E>2. Асинхронные вызовы E>3. Все элементы системы подписывались только на те сообщения, которые могли удовлетворить. Довольно сильно упрощает жизнь.
E>Для реализации использовалось TAO на разных платформах.
E>Удачи
Но в этом случае тяжело будет реализовать именно диспетчеризацию задач, например выполнение по расписанию или изменения приоритета выполнения задачи в зависимости от уровня пользователя. Авторизацию пользователей. Или например динамическое изменение версий решателей.
То есть теряются все плюсы централизации. Но появляются все плюсы децентрализации
Здравствуйте, arts80, Вы писали:
A>1) По поводу общения — у нас задача передаеться не вычислителю, а программе(ЗАГРУЗЧИК) которая порождает вычислители. То есть на удаленном компьютере запускаеться программа, готовая получить проект для вычесления. После получения проекта она запускает собственно вычислитель, вычислитель регистрируеться в сервере CORBA имен и собственно начинает вычисления. Все взаимодействие с ним производиться по зарегисрированному имени. А программа ЗАГРУЗЧИК сразу же готова принять следующий проект. У нас нет понятия решенности задачи, так как программа GUI по управлению выполнением задачи дергает вычислителей раз 50 в секунду, такова специфика задачи. A>2) У нас есть аналог диспетчера в вашем понимании, именно он забирает готовый проект из хранилища проектов и передает их ЗАГРУЗЧИКАМ, все загрузчики обязаны при старте регистрироваться в диспетчере, для этого они используют сервер имен CORBA, а именно генерируют уникальное имя и регистрируютсья под ним в сервере имен, а затем передают это имя диспетчеру.
A>http://sistem.perm.ru/service/developers/system_modeling/
A>По поводу вопросов(ИМХО): A>1) Клиент сам должен передавать задачи диспетчеру, если диспетчер не способен выполнить задачу немедленно, то он сохраняет её в своем хранилище. При передачи задачи клиент передает и свое имя в сервере имен CORBA и идентификатор задачи, этот идентификатор и дергает агент при выполнении задачи, тем самым говоря клиенту что задача с таким то ID выполнена. A>2) A> — при старте агент регистрируеться в диспетчере — у нас также сделано, по моему довольно удобная схема. A> — диспетчер передает задания агенту, а лучше не агенту, а ЗАГРУЗЧИКУ, при это ЗАГРУЗЧИК может отказатся взять задачу на выполнение если ресурсов осталось мало.
K>>Да я тоже склоняюсь к CORBA. У меня еще есть вопросы по архитектуре — точнее даже по вызовам в системе.
D результате размышлений у меня получился следующий интерфейс взаимодействия:
module netcomp {
module corba {
exception NetCompException
{
string reason; // Сообщение об ошибкеstring details; // Детали ошибки
};
//массив байтовtypedef sequence<octet> ByteContent;
//ресурсstruct Resource{
wstring resourceId;
ByteContent content;
};
//массив ресурсов typedef sequence<Resource> Resources;
//структура задачиstruct TaskStruct{
long taskId;
wstring taskxml;
Resources taskResources;
};
//массив задачtypedef sequence<TaskStruct> Tasks;
//структура проекта (включает в себя задачи) struct ProjectStruct{
long projectId;
wstring projectxml;
Tasks projectTasks;
};
//интерфейс диспетчераinterface Dispatcher {
//получить статус системы
wstring getSystemStatus(in wstring clientCorbaPath) raises( NetCompException );
//получить результат выполнения проекта
ProjectStruct getProjectResult(in wstring clientCorbaPath, in long projectid) raises( NetCompException );
//выполнить проект в системе
wstring executeProject(in wstring clientCorbaPath, in ProjectStruct project) raises( NetCompException );
//зарегистрировать удаленного агента
wstring registerRemoteAgent(in wstring remoteAgentCorbaPath) raises( NetCompException );
//установить результат выполнения задачи
wstring setTaskResult(in wstring remoteAgentCorbaPath, in TaskStruct task) raises( NetCompException );
};
//интерфейс удаленного агентаinterface RemoteAgent {
//выполнить задачу на удаленном агенте
wstring executeTask(in TaskStruct task) raises( NetCompException );
//получить статус удаленного агента
wstring getStatus() raises( NetCompException );
};
//интерфейс клиента interface Client {
//получить пароль клиента
wstring getPassword() raises( NetCompException );
//установить результат выполненияvoid setProjectResult(in ProjectStruct result) raises( NetCompException );
//получить статус клиента
wstring getStatus() raises( NetCompException );
};
};
};