Написав структуру параллельного программирования, что я пропустил?
Разъяснение. В соответствии с некоторыми комментариями я должен уточнить, что это предназначено как простая структура, позволяющая выполнять программы, которые являются естественно параллельными (так называемые неловко параллельные программы). Это не будет и никогда не будет решением для задач, требующих связи или синхронизации между процессами.
Я искал простую среду параллельного программирования на основе процессов на Python, которая может выполнять функцию на нескольких процессорах в кластере, причем основным критерием является то, что он должен иметь возможность выполнять немодифицированный код Python. Ближайший я нашел Parallel Python, но pp делает некоторые довольно забавные вещи, которые могут привести к тому, что код не будет выполнен в правильном контексте (с соответствующие модули импортируются и т.д.).
Наконец-то я устал от поиска, поэтому решил написать свое. То, что я придумал, на самом деле довольно простое. Проблема в том, что я не уверен, что то, что я придумал, просто, потому что я не мог придумать много чего. Вот что делает моя программа:
- У меня есть сервер заданий, который передает задания узлам в кластере.
-
Работы передаются серверам, слушающим узлы, передавая словарь, который выглядит следующим образом:
{
'moduleName':'some_module',
'funcName':'someFunction',
'localVars': {'someVar':someVal,...},
'globalVars':{'someOtherVar':someOtherVal,...},
'modulePath':'/a/path/to/a/directory',
'customPathHasPriority':aBoolean,
'args':(arg1,arg2,...),
'kwargs':{'kw1':val1, 'kw2':val2,...}
}
-
moduleName
и funcName
являются обязательными, а остальные необязательны.
-
Сервер node принимает этот словарь и выполняет следующие действия:
sys.path.append(modulePath)
globals()[moduleName]=__import__(moduleName, localVars, globalVars)
returnVal = globals()[moduleName].__dict__[funcName](*args, **kwargs)
-
При получении возвращаемого значения сервер отправляет его обратно на сервер заданий, который помещает его в потокобезопасную очередь.
- Когда возвращается последнее задание, сервер задания записывает вывод в файл и завершает работу.
Я уверен, что есть недостатки, которые нужно отработать, но есть ли что-то очевидное в этом отношении? На первый взгляд он кажется надежным, требуя только того, чтобы узлы имели доступ к файловой системе (ей), содержащей файл .py и зависимости. Использование __import__
имеет то преимущество, что код в модуле автоматически запускается, поэтому функция должна выполняться в правильном контексте.
Приветствуются любые предложения или критика.
EDIT: Я должен упомянуть, что у меня есть бит выполнения кода, но сервер и сервер заданий еще не записаны.
Ответы
Ответ 1
Я действительно написал что-то, что, вероятно, удовлетворяет вашим потребностям: jug. Если это не решит ваши проблемы, я обещаю вам, что исправлю все найденные ошибки.
Архитектура немного отличается: рабочие все работают с одним и тем же кодом, но они эффективно генерируют аналогичный словарь и запрашивают центральный бэкэнд "это было запущено?". Если нет, они запускают его (есть механизм блокировки тоже). Бэкэнд может быть просто файловой системой, если вы находитесь в системе NFS.
Ответ 2
Я сам занимался обработкой пакетных изображений на своих компьютерах, и моя самая большая проблема заключалась в том, что некоторые вещи нелегко или изначально распиливают и передают по сети.
например: поверхности пигмей не раскалываются. я должен преобразовать их в строки, сохранив их в объектах StringIO, а затем сбросив их по сети.
Если данные, которые вы передаете (например, ваши аргументы), можно передавать без страха, у вас не должно быть таких проблем с сетевыми данными.
Еще одна вещь приходит на ум: что вы планируете делать, если компьютер внезапно "исчезает" при выполнении задачи? при возврате данных? у вас есть план для повторной отправки задач?