storm源代码之topo的执行过程

storm集群里面nimbus是通过zookeeper来给supervisor发送指令的,那么topo从提交到执行到底是什么样的过程?nimbus和supervisor到底做了什么样的事情呢?

如何提交一个topo

要提交一个topo,命令行如下:

./storm jar mycode.jar com.topo.SimpleTopology arg1 arg2
那么这个命令背后都做了些什么呢?

storm背后的英雄:nimbus,supervisor

看似简单的topology的提交,其实背后做了很多的事情,我们看看都做了些什么。

上传topology的代码

首先由Nimbus$Iface的beginFileUpload,uploadChunk以及finishFileUpload方法来把jar包上传到nimbus服务器的/inbox目录

/{storm-local-dir}
  |
  |-/nimbus
     |
     |-/inbox                   -- 从nimbus客户端上传的jar包
        |                            会在这个目录里面
        |
        |-/stormjar-{uuid}.jar  -- 上传的jar包其中{uuid}表示
                                     生成的一个uuid
运行topology之前的一些校验

topology的代码上传之后Nimbus$Iface的submitTopology方法会负责对这个topology进行处理,首先要对storm本身,以及topology进行一些校验:

1.它检查storm的状态是否是active的

2.它套检查是否已经有同名的topology在storm中运行了

3.因为我们会在代码里面给spout,bolt指定id,storm会检查是否有两个spout和bolt使用了相同的id

4.任何一个id都不能以"_"开头,这种命名方式是系统保留的

如果以上检查都通过了,那么进入下一步

建立topology的本地目录

/{storm-local-dir}
  |
  |-/nimbus
      |
      |-/inbox                  -- 从nimbus客户端上传的jar包
      |  |                            会在这个目录里面
      |  |
      |  |-/stormjar-{uuid}.jar -- 上传的jar包其中{uuid}表示
      |                               生成的一个uuid
      |
      |-/stormdist
         |
         |-/{topology-id}
            |
            |-/stormjar.jar     -- 包含这个topology所有代码
            |                       的jar包(从nimbus/inbox
            |                       里面挪过来的)
            |
            |-/stormcode.ser    -- 这个topology对象的序列化
            |
            |-/stormconf.ser    -- 运行这个topology的配置
建立topology在zookeeper上的心跳目录

nimbus老兄是个有责任心的人,它虽然最终会把任务分成一个个task让supevisor去做,然是它时时刻刻关注着大家的情况,所以它要求每个task每隔一段时间就要给它打个招呼(心跳信息),以让它知道事情还在正常发展,如果有task超时不打招呼,nimbus会认为这个task不行了,然后重新分配。

|-/taskbeats              -- 所有task的心跳
    |
    |-/{topology-id}      -- 这个目录保存这个topology的所
        |                    有的task的心跳信息
        |
        |-/{task-id}      -- task的心跳信息,包括心跳的时
                             间,task运行时间以及一些统计
                             信息
计算topology的工作量

nimbus是个精明人,它对每个topo都会做出详细的预算:需要多少工作量(多少个task).它是根据topology定义中给的parallelism hit参数,来给spout/bolt设定task的数目,并且分配对应的task-id,把分配好的task信息写入zookeeper的/task目录下

|-/tasks                  -- 所有的task
    |
    |-/{topology-id}      -- 这个目录下面id为
        |                    {topology-id}的topology
        |                    所对应的所有的task-id
        |
        |-/{task-id}      -- 这个文件里面保存的是这个
                             task对应的component-id:
                             可能是spout-id或者bolt-id
从上表中看到task-id这个文件里面存储的是它代表的spout/bolt的id,这其实就是一个细化工作量的过程。

打比方说我们的topo里面一共只有一个spout一个bolt.其中spout的parallelism是2,bolt的parallelism是4,那么我们可以把这个topology的总工作量看成是6,那么一共6个task,/tasks/topology-id下面一共会有6个以task-id命名的文件,其中两个文件的内容是spout的id,其他四个文件是bolt的id


把计算好的工作分配给supervisor去做

然后nimbus就要给supervisor分配工作了。工作分配的单位是task,那么分配工作的意思就是把上面定义好的一堆task分配给supervisor来做,在nimbus里面,Assignment表示一个topo的任务分配信息,其中核心数据就是task->node+port,它其实就是从task-id到supervisor-id+port的映射,也就是把这个task分配给某个机器的某个端口来做。工作分配信息会被写入zookeeper的如下目录:

/-{storm-zk-root}           -- storm在zookeeper上的根
  |                            目录
  |
  |-/assignments            -- topology的任务分配信息
      |
      |-/{topology-id}      -- 这个下面保存的是每个
                               topology的assignments
                               信息包括: 对应的
                               nimbus上的代码目录,所有
                               task的启动时间,
                               每个task与机器、端口的映射
正式运行topo

到现在为止,任务都分配好了,那么我们可以正式启动这个topo了,在源代码里面,启动topo就是向zookeeper上面该topo所对应的目录写入这个topo的信息:

|-/storms                 -- 这个目录保存所有正在运行
    |                        的topology的id
    |
    |-/{topology-id}      -- 这个文件保存这个topology
                             的一些信息,包括topology的
                             名字,topology开始运行的时
                             间以及这个topology的状态
                             (具体看StormBase类)
好,nimbus干的不错,到这里为止nimbus的工作算是差不多完成了,它对topo进行了一些检查,发现没什么问题,计算了下工作量,然后再看看它的小弟们那些有空,进行额合理的分配,所有事情妥当了,就交给supervisor来做了。


supervisor领任务

我们的supervisor无时无刻不想着为大哥分忧,它每隔几秒钟就去看看大哥有没有任务分配给它。

1.首先看看storm里面有没有新的提交的没下载下来的topo代码,如果有,就下载下来,不管这个topo由不由自己负责。

2.删除那些已经不再运行的topo的代码

3.然后根据nimbus给指派的任务信息(zookeeper当中的信息),让它的小弟来做


worker执行

worker是个苦命的人,上面的nimbus,supervisor只会指手画脚,他要来做所有的脏话累活

1.它首先去zookeeper上看大哥们给它分配了那些task

2.然后根据这些task-id找出对应的topo的spout/bolt

3.计算出它所代表的这些spout/bolt会给那些task发送消息

4.建立到3里面所提到的task的连接(socket),然后在需要发送消息的时候就通过这些socket来发送

到这里为止,topo里面的组件根据parallelism被分成了多个task,而这些task被分配给supervisor的多个worker来执行。大家各司其职,整个topo运行了起来。


topo的终止

除非你显式的杀掉一个topo,否则它会一直运行下去./storm kill topoName

这个命令做了哪些操作呢?

它会把zookeeper上面/tasks,/assignments,/storms下面关于这个topology的数据都删除掉,这些数据之前都是nimbus创建的,还剩下taskbeats以及taskerrors下的数据没有清楚,这些数据会在supervisor下次从zookeeper上同步数据的时候删除。这样数据就彻底删掉了。






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值