1

У меня есть приложение, в котором у меня есть пять разных задач. Каждая из этих пяти задач выполняется в разные периоды времени в определенный день. Я буду развертывать это приложение на 4 разных машинах.Как иметь разные машины, выполняющие разные задачи?

В общем, я выполнял все эти пять различных задач на одной машине, выбирая лидера между этими четырьмя машинами, используя Apache Zookeeper. Но при таком подходе другие три машины будут сидеть без дела, поэтому я думал, есть ли способ, которым у меня могут быть разные машины, выполняющие разные задачи? Это означает, что каждая из этих четырех машин запускает некоторые задачи из этих пяти, но не две машины, выполняющие одну и ту же задачу.

Может ли кто-нибудь представить пример, как я могу это сделать?

Обновление: -

У меня нет какой-либо зависимости между различными задачами. Все они независимы друг от друга.

+0

Есть ли зависимость между различными задачами? –

+0

@OferLando Нет, между различными задачами нет зависимости. Они независимы друг от друга. – john

+0

Посмотрите на этот проект, который я написал. Он делает что-то подобное. Вы могли бы использовать его напрямую или в качестве примера: https://github.com/NirmataOSS/workflow – Randgalt

ответ

0

Я бы пять узлов: pending_tasks, completed_tasks, running_tasks, workers и queues. pending_tasks - это узел, который содержит задачи, как новые, так и те, которые будут перезапускаться из-за сбоев в рабочих узлах. completed_tasks содержит детали выполненных заданий. running_tasks выполняет задачи, которые назначаются работникам. В реализации PoC я сделал, как только я использовал POJO, закодированный в XML, для хранения сведений о задачах. Узлы в pending_tasks, completed_tasks и running_tasks - все постоянные узлы.

workers содержит эфемерные узлы, которые представляют доступные рабочие. Учитывая, что они являются эфемерными, эти узлы сигнализируют об отказах рабочих. queues напрямую связан с workers: есть узел в queues для каждого узла в workers. Узлы в queues используются для выполнения задач, назначенных для каждого из рабочих.

Теперь вам нужен мастер. Мастер отвечает за три вещи: i) смотреть pending_tasks для новых задач; ii) смотреть workers, чтобы зарегистрировать новый queues, когда прибудут новые рабочие, и вернуть задания в pending_tasks, когда рабочие пропали; и iii) опубликовать результат задач в completed_tasks (когда я это сделал, результат будет проходить через механизм уведомления публикации/подписки). Кроме того, мастер должен выполнить некоторую очистку при запуске, учитывая, что работники могут выйти из строя во время простоя мастера.

Мастер алгоритм заключается в следующем:

at (start-up) { 
    for (q -> /queues) { 
    if q.name not in nodesOf(/workers) { 
     for (t -> nodesOf(/queues/d.name)) { 
     create /pending_tasks/t.name 
     delete /running_tasks/t.name 
     delete /queues/d.name/t.name 
     } 
     delete /queues/d.name 
    } 
    } 

    for (t -> nodesOf(/completed_tasks)) { 
    publish the result 
    deleted /completed_tasks/c.name 
    } 
} 

watch (/workers) { 
    case c: Created => register the new worker queue 
    case d: Deleted => transaction { 
    for (t -> nodesOf(/queues/d.name)) { 
     create /pending_tasks/t.name 
     delete /running_tasks/t.name 
     delete /queues/d.name/t.name 
    } 
    delete /queues/d.name 
    } 
} 

watch (/pending_tasks) { 
    case c: Created => transaction { 
    create /running_tasks/c.name 
    create persistent node in one of the workers queue (eg, /queues/worker_0/c.name) 
    delete /pending_tasks/c.name 
    } 
} 

watch (/completed_tasks) { 
    case c: Created => 
    publish the result 
    deleted /completed_tasks/c.name 
} 

Алгоритм работника заключается в следующем:

at (start-up) { 
    create /queue/this.name 
    create a ephemeral node /workers/this.name 
} 

watch (/queue/this.name) { 
    case c: Created => 
    perform the task 
    transaction { 
     create /completed_tasks/c.name with the result 
     delete /queues/this.name/c.name 
     delete /running_tasks/c.name 
    } 
} 

Некоторые замечания о том, когда я думал об этом проекте. Во-первых, в любой момент времени не выполнялись задачи, нацеленные на одни и те же вычисления. Поэтому я назвал задачи после проведенных вычислений. Таким образом, если два разных клиента запросили одни и те же вычисления, только один будет успешным, поскольку только один сможет создать узел /pending_tasks. Аналогично, если задача уже запущена, создание узла /running_task/ потерпит неудачу, и никакая новая задача не будет отправлена.

Во-вторых, могут быть произвольные сбои как у мастеров, так и у рабочих, и никакая задача не будет потеряна.Если рабочий не работает, просмотр событий удаления в /worker вызовет переназначение задач. Если мастер терпит неудачу, и любое заданное число рабочих провалится до того, как новый мастер будет установлен, процедура запуска переместит задачи обратно на /pending_tasks и опубликует любой ожидающий результата.

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

Смежные вопросы