分布式任务分发

小王做的煎饼很好吃,于是他决定开一家卖煎饼的店。店铺开张时只有他一个人,他既要做煎饼又要在柜台打包煎饼和记账,随着名气越来越大,有越来越多的人慕名而来。但是也有很多人看到排队时间很长而放弃购买。小王决定招聘一个服务员负责打包煎饼和记账,这样小王就能专注于做煎饼,而顾客也不用等那么长时间。

几年之后,随着旅游业的发展,有很多外地人也慕名而来尝试小王的煎饼,这时候小王和他的服务员已经忙不过来了,小王决定开几家分店。在开分店时,小王为了避免口碑的下滑,要求每个分店都在早上去小王那里拿走新鲜的原材料。这样,小王既保证了煎饼的质量,又提升了制作煎饼的速度,还能让顾客排队时间变短,小王也能赚到更多的钱。

计算机在处理一些运算量/吞吐量大的任务时,也会遇到性能瓶颈问题。这时候可以选择更换更强劲的CPU,更大的内存来解决这个问题(就像刚开始小王招聘一个服务员来减少顾客的排队时间),但是如果任务量过大的话还是会遇到性能瓶颈问题。这时候可以选择加机器,把一个大任务拆分为几个小任务让不同的机器来做这些小任务(就像小王开分店一样)。

在写本文时,参考了Google的MapReduce论文,把其中任务分发这部分内容单独拿了出来,而没有考虑具体的Map和Reduce操作。

架构图

在进行任务分发时,Client节点通过与Master节点之间的通信来完成任务的获取,任务的处理操作,其架构图如下所示。
在这里插入图片描述

Master负责存储任务的状态
Client节点负责获取任务和执行任务

Client与Master节点之间的通信

下图中->表示网络请求方向

  1. 请求任务阶段,Client1和Client2向Master节点发出任务请求
  2. 分配任务阶段,Master节点向Client1和Client2发送分配给各个节点的任务
  3. 汇报任务处理状态阶段,Client1和Client2向Master节点汇报其所做任务是否完成

该图的绘制格式来源于PBFT一文,个人感觉通过这种方式绘制通信方向会更加直观一些。

在这里插入图片描述

任务的状态

其中每个任务都有三种状态,分别是未分配,正在处理和已完成。
在处理任务时,如果Master长时间没有收到Client节点关于任务状态的汇报,就认为该任务处理失败,标记为未分配,重新执行该任务。
在这里插入图片描述

任务是如何分配的?

在Master节点,存储一个关于任务状态的数组,这样每当一个Client请求任务时,就可以遍历该数组找到一个还未分配的任务,将其分配给Client。

const (
	unassign  = 0
	inprocess = 1
	completed = 2
) //任务的三种状态

func main() {
   
	m := Master{
   }
	m.task = make([]int, 10) //存储任务状态的数组
}

在此之前,Master节点需要先检查所有的任务是否已经完成,思路很简单,就是遍历整个数组,看其所有的任务是否已经完成,已经完成的话就不再分配任务。遍历时可以采用&&操作,只要其中一个任务还没有完成,那么最终结果就是false

taskDone := true

for
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值