strom之nimbus

Storm

Storm的主线主要包括4条:nimbus, supervisor, worker和task。

Nimbus

要了解nimbus的具体做的操作,可以从提交一个topology的流程开始。

1.1  Prepare

Nimbus启动时候,运行了一个Thrift Server。它会在topology提交之前做以下四个工作。

      (1)  清理一些中断了的topology(nimbus目录下/storm.local.dir/stormdist下存在,zk中            storms/topologyid中不存在的topology): 删除ZK上相关信息(清理tasks/topologyid; storms/topologyid; assignments/topologyid这个三个目录)。

      (2)  将storms/下所有的topology设置为启动状态: 能转换成startup状态的两种状态分别是:killed和rebalancing。nimbus的状态转换是很有意思的事情,killed状态的topology在nimbus启动的时候会被干掉;rebalancing状态的topology在nimbus启动的时候会重新分发任务,状态会变成rebalancing的上一个状态。

 

举例: 当某个topology提交的时候,会被设置成active状态,假设storm集群增加机器了,你希望重新分发任务,可以将状态转换成rebalance状态,转换成这个状态要做这几件事:

首先,启动一个延迟TOPOLOGY-MESSAGE-TIMEOUT-SECS秒执行的事件,将当前状态转换成do-rebalance状态,在这之前会将当前topology的状态设置成rebalancing状态(注意设置和转换的区别,设置就是指将ZK上存储的topology的状态进行重新设置)。

然后,将rebalancing的状态转换成do-rebalance, 也就是将任务重新分发。

最后将状态设置成rebalancing的上一个状态active。

      (3) 每间隔NIMBUS-MONITOR-FREQ-SECS长时间将ZK上/storms 下所有的topology状态转换成monitor状态,并且将不活跃的storm清理掉。只有当状态为active和inactive的时候,才能转换成monitor状态,转换成该状态就是将任务重新分发,监控是否与上一次的分配情况不同,如果存在不同,则替换,这个过程ZK上存储的topology的状态是不会被设置的。

 

      (4)  删除过期的jar: 过期时间为NIMBUS-INBOX-JAR-EXPIRATION-SECS。每间隔NIMBUS-CLEANUP-INBOX-FREQ-SECS长时间进行一次清理。

1.2  Submit topology

1.2.1  Submit

以下是提交一个topology的执行流程概述

      (1)  检查:检查所提交的topology是否已经是active状态,如果是,抛出异常。

      (2)  计数器:计数器+1,用来计算共提交了多少topology。

      (3)  为这个topology生一个id。

      (4)  计算要启动的acker的相关信息,每个acker都是一个bolt。根据配置的信息获取并发数等。

      (5) 获取topology的code和config。

      (6) 为该topology建立心跳目录(ZK:storm-zk-root/taskbeats/topologyid)。

      (7) 为该topology分配任务。

      (8) 设置storm状态为active。

1.2.2 Task assigned

这个是nimbus的重点,分配任务的流程:

(1)  获取所有的node+port:分配任务的目的就是将tasks分配到具体的node+port。

2)   获取该topology已经分配了的任务(如果是新提交的topology,则为空)。

(3)  为每个需要分配的task分配到具体node+port。合并(1)和(2)中所有的node和port。具体为什么要这样,还不是很清楚。因为通过(1)应该是可以获取所有的node+port。

(4)  将2)中需要重新分配的task的启动时间不变,其他新分配的任务的时间设置为当前时间。

(5)   将以上的信息Assignment写入到ZK中。

       1.2.3          scratch?

分配任务主要分为两种情况,代码中用scratch?来标识两种不同的情况(正常的分配任务和rebalance状态转换)。1.2.2中所说的需要分配的任务暗指此处的两种任务分配情况。

(1)     rebalance状态转换

这种原因导致的重新分发任务,与正常的分配任务的区别在于两点:

第一:所有的任务都认为是活跃任务,即认为任务心跳都未超时。

第二:所有的任务都需要重新分配,即认为所有端口都是空闲的端口,允许被分配任务。

举例说明:

假设:提交的topology确定有10个task, taskid分别为1,2,3,…10。有两个supervisor(n

ode1和node2),每个supervisor可用的端口号为{6001, 6002, 6003}。

 

分配任务的目标是尽可能负载均衡,即每个node均衡,每个端口均衡, rebalance情况

下分配的结果为:

tasked

node+port

1、7

node1:6001

3、9

node1:6002

5

node1:6003

2、8

node2:6001

4、10

node2:6002

6

node2:6003

 

(2) 正常分配任务:

正常分配任务比rebalance多考虑两个问题,考虑task的心跳是否超时和哪些端口上分配的任务是符合负载均衡的,可以不需要重新分发。所以要重新分发的task是那些心跳超时和所在端口没有分配均衡的那些任务。

 

nimbus用了一个叫task-heartbeat-cache来存储task的心跳时间,而不是直接用写入到zk上的心跳时间,这么做的目的是防止各个node上面的时间不同步。

 

举例说明:

假设提交的topology,跟上个例子相同。确定有10个task, taskid分别为1,2,3,…10。有两个supervisor(node1和node2),每个supervisor可用的端口号为{6001, 6002, 6003}。

首先,重新分配任务时,会先判断心跳超时的task,假设task1和task6心跳超时,task1和task6需要重新分配。

然后,判断哪些端口的分配是符合负载均衡的要求。 判断过程是这样的:共10个task,6个端口,按照负载均衡原则,应该是4个端口上分配两个task,2个端口上分配1个task。依次判断哪些端口不符合要求。如果按顺序来判断,node1:6001和node2:6002是不符合要求的,他们应该要被分别分配2个任务。所以两个端口的任务也需要重新分发。

最后,确定要重新分发的任务是1、4、7和10,可用的端口号是node1:6001和node2:6002。

按照每个node均衡,每个端口均衡的分配原则,分配结果如下:

tasked

node+port

1、7

node1:6001

4、10

node2:6002

 

 

 

 

 

 

你可能感兴趣的:(storm,nimbus)