【问题标题】:Algorithms for rebalancing round robin assignments重新平衡循环分配的算法
【发布时间】:2016-09-14 22:55:50
【问题描述】:

我有一个具有以下属性的系统:

  1. 有些工人在工作。可以添加或删除工人。每个工作人员可以同时运行多个作业。

  2. 有工作。这些作业永远运行(无限期)并分配给工人。可以添加或删除作业。

我正在使用循环法在启动时将工作分配给工人,这工作得很好。

但是,我想在添加和删除工作人员以及添加和删除工作时重新平衡分配给工作人员的工作。

虽然可以在发生上述任何更改时使用循环算法重新分配所有内容,但所做的更改将超出要求。

换句话说,是否有任何循环再平衡算法可以使分配的差异/更改最少?

【问题讨论】:

  • 一名工人如何同时同时从事多项工作?您的描述中还有一个隐含的假设,即一个工人可以中断他的工作,而另一个工人可以恢复这个被中断的工作。这是一个已解决的问题,还是您希望您的问题的答案能够解决此问题?
  • 一个工作人员可以同时处理多个工作,因为每个工作都是作为 goroutine 启动的。换句话说,每个作业都可以被认为是一个线程(尽管 go 例程不是线程)。这项工作相对简单:将消息从数据库推送到消息总线,因此将工作切换到另一个工作人员是微不足道的。
  • 一个工作可以同时分配给多个worker吗?
  • @SauravSahu No. 每个工作只能分配给 1 个工人。

标签: algorithm round-robin


【解决方案1】:

我假设,您的循环方法以下列方式分配作业:

W1   W2   W3   W4
-----------------
J1   J2   J3   J4
J5   J6   J7   J8
J9

添加新工作非常简单。您只需要记住您分配的最后一个工作的工人(循环算法的状态,将在下面称为最后一个工人)并将新工作分配给下一个工人.增加最后一个工人。

如果您想删除作业(例如上例中的J7),请执行以下操作:首先,删除作业:

W1   W2   W3   W4
-----------------
J1   J2   J3   J4
J5   J6        J8
J9

然后选择最后一个工人的最后一个工作,并将其重新分配给失去工作的工人(除非被删除的工作是最后一个工作):

W1   W2   W3   W4
-----------------
J1   J2   J3   J4
J5   J6   J9   J8

减少最后一个工人

如果要添加工人,请执行以下操作:选择最后一个工人的最后一个工作并将其分配给新工人,直到新工人的工作数量等于或小于该工人的工作数量第一个工人。

W1   W2   W3   W4   W5
----------------------
J1   J2   J3   J4   J8
J5   J6   J9

相应地更新最后一个工人。

如果您已经具备上述所有条件,那么移除一个工作人员非常简单:只需接受其所有工作并一次添加一个即可。例如。如果你删除W2:

W1   W3   W4   W5
----------------------
J1   J3   J4   J8
J5   J9   J2   J6

根据数据的大小,您应该使用适当的数据结构来提高效率。但我相信你知道要使用什么结构。

【讨论】:

  • 在某些情况下,您的解决方案并不十分理想,因为可以通过更少的工作转移来保持同样良好的平衡。例如,在上面的示例中从W3 中删除作业J7 之后,让我们从W2 中删除J6。您的算法现在会将工作 J8W4 转移到 W2 以保持平衡,而保持工作分配原样会更有效(就所需转移的数量而言),而不是 重新排序工作人员,以便W2 移动到工作人员列表的末尾。
  • 在第一种情况下,假设我们有多达J7 个工作(没有J8J9),然后删除J6。那么您不认为将J7 移动到W2 会产生不必要的开销吗?
  • 你说的都是对的。我并不是说这是一个完美的解决方案。合并工人重新排序应该很容易(例如,将当前工人的工作数量与第一个工人的工作数量进行比较)。但是,批量插入和删除是完全不同的故事。
【解决方案2】:

减少或优化作业移动的数量:

创建一个对(workernumOfJobsAssigned)的列表(例如,workers),目前分别维护一个变量 maxJobsToAnySingleWorker

达到平衡状态后(即所有workers 拥有相同数量的工作),将maxJobsToAnySingleWorker 增加1,然后添加新工作。

Start with maxJobsToAnySingleWorker = 0

For addition of a Job:
    Set Done to false
    for each worker in workers 
        if numOfJobsAssigned < maxJobsToAnySingleWorker
            Increase worker.numOfJobsAssigned by 1
            Set Done to true
            break
    if Done is false (equilibrium state)
        increase maxJobsToAnySingleWorker by 1
        Increase FirstWorker.numOfJobsAssigned by 1


For removal of a Job from a worker, say myWorker:
    Done = false
    Remove Job
    if myWorker.numOfJobsAssigned == maxJobsToAnySingleWorker-1
         Do nothing
    else
        for each worker in workers 
            if (numOfJobsAssigned > 1) and (numOfJobsAssigned == maxJobsToAnySingleWorker)
                Delegate Job from worker to myWorker
                Decrease worker.numOfJobsAssigned by 1
                Done = true
                break
        if worker is lastWorkerInList
            Decrease maxJobsToAnySingleWorker by 1

按照上述逻辑,工人的移除可以通过移除离开工人的工作+向留下工人增加工作来完成strong> 一个一个。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-01-20
    • 2016-07-28
    • 1970-01-01
    • 1970-01-01
    • 2021-01-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多