-
Notifications
You must be signed in to change notification settings - Fork 84
Description
假设一个job由很多个task组成,一个task又由很多个instance组成。
问题主要归结为:比如某个节点突然down了,那么对于这个节点的所有要运行的job都会失败。比如下面这个case,对于一个域名下有十个节点,现在要进行配置文件分发的Task,结果其中一个节点突然down了,那么最终结果是9个节点返回成功,1个节点返回失败,可以说是9个instance成功,1个instance失败,最终结果不能算这个Task是失败吧?因为标记为失败后,又得重新调度整个Task,所有的instance又得重新跑。
怎么解决?
方案一:把失败的instance重新组成一个task,丢到队列里面调度,并且设置最大调度次数,每次调度后就把count加1,直到超过最大调度次数后判断为失败,更新到数据库。
这个方案的缺点:一旦down的节点恢复之后,需要有一个守护去轮询数据库找到这个down的节点还有哪些任务要做,然后依次做完。这种在编程逻辑上是很复杂的,因为设计到要找到哪些任务要做,而且其实是很浪费资源的,因为明知道这个节点其实是down的,没必要(可能说可以根据网络响应的错误类型来判断是否要调度,但是这样的方法是最优的吗?),现在的版本就是这样的。
方案二:做一个任务的堆积,一旦某个节点down了,就把这个节点要做的task都堆积起来,这种堆积不应该是队列,而是保证最新的task就行,类似应该是K-V这种,保证每种task类型只有一个最新的task。这个方案不知道该怎么实现比较好?
总结下:需要解决一个问题,就是task执行失败的情况下(节点半死不活),怎么把task更优雅的,并且不重复的保存到一个"failed_task_to_do"的结构中(不应该是队列,最好是磁盘),等到节点ok了,把所有的该节点的tasks都执行了。