Пример программы dispy зависает

TL;DR: я не могу заставить базовый dispy пример кода работать правильно. Почему бы и нет?

Подробности:

Я пытаюсь разобраться с распределенной обработкой в ​​python и подумал, что библиотека dispy звучит интересно из-за к исчерпывающему набору функций.

Однако я пытался следовать их основному каноническому примеру программы, и у меня ничего не получалось.

  • Я установил диспи (python -m pip install dispy)
  • Я перешел на другую машину с тем же адресом подсети и запустил python dispynode.py. Кажется, это работает, так как я получаю следующий вывод:
    #P5# #P6#
  • Вернувшись на свой клиентский компьютер, я запускаю пример кода, загруженный с http://dispy.sourceforge.net/_downloads/sample.py, скопировано сюда:


# function 'compute' is distributed and executed with arguments
# supplied with 'cluster.submit' below
def compute(n):
    import time, socket
    time.sleep(n)
    host = socket.gethostname()
    return (host, n)

if __name__ == '__main__':
    # executed on client only; variables created below, including modules imported,
    # are not available in job computations
    import dispy, random
    # distribute 'compute' to nodes; 'compute' does not have any dependencies (needed from client)
    cluster = dispy.JobCluster(compute)
    # run 'compute' with 20 random numbers on available CPUs
    jobs = []
    for i in range(20):
        job = cluster.submit(random.randint(5,20))
        job.id = i # associate an ID to identify jobs (if needed later)
        jobs.append(job)
    # cluster.wait() # waits until all jobs finish
    for job in jobs:
        host, n = job() # waits for job to finish and returns results
        print('%s executed job %s at %s with %s' % (host, job.id, job.start_time, n))
        # other fields of 'job' that may be useful:
        # job.stdout, job.stderr, job.exception, job.ip_addr, job.end_time
    cluster.print_status()  # shows which nodes executed how many jobs etc.

Когда я запускаю это (python sample.py), оно просто зависает. Отлаживаю через pdb, вижу в итоге висит на dispy/__init__.py(117)__call__(). Строка читается как self.finish.wait(). Finish — это просто поток Python, так как wait() затем переходит в lib/python3.5/threading.py(531)wait(). Он зависает, как только он попадает в ожидание.

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

cluster = dispy.JobCluster(compute, nodes=['localhost'])
cluster = dispy.JobCluster(compute, nodes=['*'])
cluster = dispy.JobCluster(compute, nodes=[<hostname of the remote node running the client>])

Я пробовал работать с раскомментированной строкой cluster.wait() и получил те же результаты.

Когда я добавил ведение журнала (cluster = dispy.JobCluster(compute, loglevel = 10)), я получил следующий вывод на стороне клиента:

14.06.2016, 10:27:01 asyncoro — версия 4.1 с уведомлением о вводе-выводе epoll
dispy – Сохранение информации об устранении сбоя в «_dispy_20160614102701»
14.06.2016 10:27:01 dispy – Незаконченные задания: 0
14-06-2016 10:27:01 dispy – Незавершенные задания: 1
14.06.2016, 10:27:01 dispy - Незаконченные задания: 2
14.06.2016 10:27:01 dispy - Незаконченные задания: 3
14-06-2016, 10:27:01 dispy - Незавершенные задания: 4
14-06-2016 10:27:01 dispy - Незавершенные задания: 5
14-06-2016 10:27:01 dispy - Незавершенные задания: 6
2016-06- 14 10:27:01 dispy - Незавершенные задания: 7
14.06.2016 10:27:01 dispy - Незавершенные задания: 8
14-06-2016 10:27:01 dispy - Незавершенные задания: 9
2016-06-14 10:27:01 dispy - Отложенных заданий: 10

Это не кажется неожиданным, но не помогает мне понять, почему задания не выполняются.

Для чего это стоит, вот _dispy_20160614102701.bak:

'_cluster', (0, 207)
'compute_1465918021755', (512, 85)

и аналогично _dispy_20160614102701.dir:

'_cluster', (0, 207)
'compute_1465918021755', (512, 85)

У меня нет догадок, если только я не использую нестабильную версию.


person Scott Mermelstein    schedule 14.06.2016    source источник
comment
У меня тоже такая проблема. Хотелось бы узнать есть ли решение этой проблемы?   -  person lskrinjar    schedule 01.07.2016
comment
Я не нашел ни одного. На самом деле, я отказался от диспи, так что даже не удосужился назначить награду за это. Я также попробовал scoop, который на первый взгляд делает именно то, что мне нужно, но у него очень странный, произвольное ограничение на максимальное количество процессоров, которое я мог бы с пользой добавить . Я сдался и решил использовать базовый popen ssh и написать свой собственный планировщик.   -  person Scott Mermelstein    schedule 01.07.2016
comment
@ThomasGuenet Вы предложили редактирование, которое я собираюсь отклонить. Правка неуместна, потому что вы меняете то, что я на самом деле сказал, что сделал. Я пробежал python dispy.py, а не только dispy.py. Есть разница в том, как они работают, в том, что ваш путь — это модуль. Эта разница могла быть причиной того, что программа зависала. Таким образом, ваше редактирование неуместно, но может дать хороший ответ. Запишите это как ответ, показывающий, как запуск только dispy.py вместо python dispy.py решит проблему. Если вы покажете это убедительно, вы ответите на этот вопрос.   -  person Scott Mermelstein    schedule 05.01.2017
comment
@ScottMermelstein Я предложил вам изменить python dispynode.py, выполняемый из оболочки, на dispynode.py напрямую: эта команда позволяет запускать задания на узле. Я использовал dispy вчера и столкнулся с той же проблемой и решил ее сегодня на своем компьютере. Я просто не знаю, та ли это проблема, что и у вас. Я опубликую это.   -  person ThomasGuenet    schedule 06.01.2017


Ответы (3)


При первой настройке и использовании dispy в сети я обнаружил, что мне нужно указать IP-адрес клиентского узла при создании кластера заданий, см. ниже:

cluster = dispy.JobCluster(compute, ip_addr=your_ip_address_here)

Посмотрите, поможет ли это.

person Dave    schedule 12.07.2017
comment
Большое спасибо! Это мой случай. - person dismine; 23.11.2017

Если вы просто запускаете sample.py на своем клиенте, измените следующее в своем основном выражении:

cluster = dispy.JobCluster(compute, nodes=['nodeip_1','nodeip_2',.....,'nodeip_n])

Затем запустите его в своей среде IDE или через оболочку.

Надеюсь, это поможет.

person user6466166    schedule 14.06.2016
comment
Спасибо за Ваш ответ. Я пробовал nodes=['nodename'] раньше, и это не сработало. Основываясь на вашем предложении, я попробовал nodes=['nodeip'], и он все еще зависает. По какой-то причине он никогда не общается с клиентом. - person Scott Mermelstein; 14.06.2016
comment
Если ваш кластер находится в той же локальной сети. На узле попробуйте запустить скрипт dispynode таким образом. python dispynode.py -i pcname(или IP-адрес) Затем запустите скрипт, как я описал в предыдущем комментарии выше. - person user6466166; 14.06.2016
comment
Использование любого из них дает мне OSError: [Errno 99] Cannot assign requested address (в строке 252 dispynode.py: slf.tcp_sock.bind((ip_addr, node_port)). - person Scott Mermelstein; 14.06.2016

Перед выполнением python sample.py dispynode.py все еще должен работать на локальном хосте или другом компьютере (обратите внимание, что другой компьютер должен быть в той же сети, если вы не хотите указывать сложные параметры).

Я столкнулся с той же проблемой и решил ее следующим образом:

  • откройте терминал и выполните: $ dispynode.py (не завершайте его)
  • откройте второй терминал и выполните: $ python sample.py

Не забывайте, что функция compute состоит в ожидании определенного времени, выходные данные должны появиться как минимум через 20 секунд после выполнения sample.py.

person ThomasGuenet    schedule 06.01.2017
comment
Что ж, попробовать стоило, но, кажется, не имеет значения, использовал ли я python dispynode.py или только dispynode.py. Я получаю тот же результат с моим клиентом - он зависает в состоянии ожидания(). Я пробовал без установки узлов в кластере и с установкой узлов как ['hostname'], так и ['hostip']. Во всех случаях я получаю те же результаты с dispynode.py, что и с python dispynode.py. - person Scott Mermelstein; 06.01.2017