Несогласованное время выполнения задач с использованием рабочих RQ с py-redis
Я запускаю программу Python, в которой каждый экземпляр программы использует уникальный redis-сервер, а рабочие RQ используются для удаленного выполнения задач. Программа запускается на кластере PBS, а рабочие RQ запускаютсяmpirun
. Это нормально работает, но в разных экземплярах программы я вижу большие расхождения во времени. Например, одна и та же программа на одном узле может работать в десять раз дольше на другом. Я хотел бы понять, почему это так; некоторые удаленные узлы задерживают чтение памяти или это связано со структурой моей программы?
Задачи, поставленные перед рабочими RQ, достаточно дороги и включают в себя ряд import
s из каталога модуля - я попытался свести его к основным шагам ниже.
Вот файл my_module.available_classes.py
:
import my_module.available_methods
class my_class():
def __init__(self):
# set method_1 as function object written elsewhere in the module,
# so it can be easily replaced with alternatives
self.method_1 = my_module.available_methods.option_1
def call_method_1(self, **kwargs):
# Wrapper for method_1 object; expensive calculation
self.method_1(**kwargs)
А также my_module.remote_subroutine.py
:
import my_module.available_classes
def expensive_step( args_for_expensive_step ):
# instance of class defined within the module
c = my_module.available_classes.my_class()
# call expensive method repeatedly
while True:
c.call_method_1()
if c.is_finished():
break
Затем, my_module.my_program.py
бежит
from rq import Queue
import my_module.remote_subroutine
queue = Queue(queue_id, connection=redis_conn)
queue.enqueue(
my_module.remote_subroutine.expensive_step,
args_for_expensive_step)
Я читал в документации RQ, что может быть полезно использовать пользовательский рабочий сценарий с модулями, предварительно загруженными перед форкованием. Я пробовал следующее, но проблема с синхронизацией все еще не устранена.
import redis
from rq import Queue, Connection
# Preload libraries:
import my_module
# Parse command line arguments
# -> set redis_host_name, redis_port_number, queue_id
redis_conn = redis.Redis(
host = redis_host_name,
port = redis_port_number
)
with Connection( redis_conn ):
w = Worker( [str(queue_id)] , connection=redis_conn)
w.work()
Мой вопрос: не позволяет ли структура моей программы предварительную загрузку? my_module
, так что работники RQ имеют немедленный доступ к method_1
так далее? В противном случае, почему некоторые рабочие RQ намного медленнее, чем другие, выполняют ту же задачу? Обратите внимание, что в экземплярах программыexpensive_step
вычисляется для разных входных данных, и тайминги согласованы в пределах экземпляров, т.е. требуется 100 секунд для каждой из 20 задач наmy_program instance 1
, и 1000 за каждую из 20 задач на my_program instance 2
.
Спасибо за любую помощь в понимании этого.