跳转到: 导航, 搜索

Ceilometer/蓝图/任务分发

Ceilometer 中央代理的任务分发服务

简介

目前有一个中央代理轮询其他服务,这种架构非常脆弱,因为它存在明显的 SPOF(单点故障)。 确实,当中央代理宕机时,轮询过程就无法执行。 此外,如果需要轮询的服务数量巨大,那么单个代理无法很好地扩展。

我们希望能够同时运行多个中央代理,并能够将工作分配给它们。 因此,如果我们有 n 个代理和 p 个需要轮询的资源,我们希望将这 p 个任务分配到这 n 个节点上。

为了协调代理集群,我们将解决方案分为两个主要部分。 第一部分是关于组员管理服务,旨在创建节点组,并在发生故障时通知其他节点。 第二部分是关于任务分发服务,一旦我们有了代理组,我们希望将任务分发到该组中。

此蓝图的目的是提出一种架构,通过利用组员管理服务来动态地将任务负载均衡到给定的组中。

任务分发服务

此服务将建立在组员管理服务之上,实际上,想法是创建和监控两个组。 第一个是中央代理组“/agents”,第二个是资源组“/resources”。

一旦我们能够监控这两个组,我们就需要一种将任务分配给代理的机制。 为了执行此任务,我们使用组中领导者的概念,领导者是所有成员都同意的特殊成员。 在我们的用例中,我们将请求组员管理服务在中央代理组中选举一个领导者,该领导者将负责将任务分配给其他代理。

以下是架构概述: Task distribution bp.png 领导者将监听代理组和资源组的任何状态变化。 在非领导者代理发生故障时,领导者将根据调度策略重新分配任务给剩余的代理。 我们可以对资源组执行相同的方式,以便当某些资源发生故障时,领导者会收到通知并可以重新分配任务。

作为任何其他服务,当前是领导者的代理可能会发生故障,因此为了使其具有高可用性,我们需要能够在发生故障时动态地重新选举新的领导者。 这属于组员管理服务的一部分。

我们对轮询任务没有实时约束,因此当代理在轮询资源之前发生故障时,我们只需将任务恢复到剩余的代理上,稍微延迟资源的轮询不会有问题。

Python API

  • resource_join_group(resources_group_id)

此函数允许加入资源组并发送心跳以建立组员关系。 资源将发布其地址作为其功能的一部分。

  • agent_join_group(agents_group_id)

此函数允许加入代理组,加入组后将接受要轮询的资源。 此过程还将参与领导者选举,如果它被选举,它将创建一个承担领导者角色的进程。

资源和代理算法

资源算法

资源只需发送心跳,这由组员管理服务在加入组时自动管理。

代理算法

代理更复杂,它由两个进程组成,第一个是轮询进程,它轮询资源并接受新的要轮询的资源,第二个是领导者进程,它将任务分配给代理。

轮询进程

变量

   list_resources = [ ] # list of resources address to poll
   is_leader = false
  • 收到新的资源地址时
   add resource address in list_resources
  • 领导者发生故障时
   election_leader()
   if current agent elected then
       is_leader = true
       notify_leader_process()

领导者进程

function schedule_resources_to_agents(): 此函数根据调度策略将任务分配给代理。

  • 代理组状态发生变化时
   schedule_resources_to_agents()
  • 资源组状态发生变化时
  schedule_resources_to_agents()

调度引擎

我们需要定义一个调度策略:一种将 p 个任务从给定的任务集合分配到 n 个节点从给定节点集合上的算法。 这些策略可以非常简单:以下是一些示例。

  • 轮询法:任务使用“轮询”方式分配到节点上。

策略。

  • 单任务队列:任务存储在 FIFO 中。 当代理需要执行

某些工作时,它会从这个 FIFO 中取出一个任务。

  • 工作窃取策略:每个中央代理都有自己的任务 FIFO,从中

弹出下一个要运行的任务。 如果代理没有工作(其 FIFO 为空),它可以从另一个代理“窃取”一个任务。