Apache Storm 学习:Supervisor,Worker,Executor,Task

来源:互联网 发布:ubuntu 卸载apache2 编辑:程序博客网 时间:2024/06/12 01:47

成功安装Storm环境之后,接下来的事情就是使用这个分布式实时计算框架来完成原来的读数据文件并导入MongoDB的工作了。

代码不复杂,根据文档可以很快的实现。但是有几件事情觉得有必要记录下来。

1)IBasicBolt 和 IRichBolt

根据文档,为了简化代码使用了BaseBasicBolt作为基类,却导致Spout收到大量的fail,为什么?研究发现,根源是我们超时时间缺省只有30s,实在太短(任务有一个读30M的文件),但另一方面也是这个BasicBolt帮我们对ack/fail进行了管理,代码是省了,但其实并不方便,至少觉得不如自己处理更有效果,也不直接。所以,后来修改为继承IRichBolt,还是自已主动Ack吧。

2)任务分解

开始设计按原来的逻辑,在Bolt中完成全部工作:读文件,解析,写数据库。但是发现对于30M的大文件来说,这个过程非常漫长导致超时,加大超时时间能解决问题。

conf.setMessageTimeoutSecs(600);

但不是根本办法,所以又优化一下,看看写库动作能否拆到其它任务中去,于是又新建一个MongoRecordBolt,负责写一条记录。

builder.setBolt("complain-day", new ComplainBolt(),TASK_NUMBER)  .shuffleGrouping("csv-scanner", "complain.day");builder.setBolt("mongo-complain-day", new MongoRecordBolt(),2*TASK_NUMBER)  .shuffleGrouping("complain-day"); 

从Spout中分解任务到Bolt时使用了streamId,但是每个解析Bolt将写库任务丢出去时,可以省了。
修改之后,从最终效果来看,还是比较明显的。

3)并行度及UI

先说并行度的几个概念。supervisor | worker | executor | task

  • supervisor 工作节点,与nimbus控制节点对应,一般会对应一个服务器作为节点。
  • worker 工作进程,我们在storm.yaml中为每个supervisor配置slot个数及端口,每个slot对应一个worker,每个worker会启动独立进程。
  • executor 执行器,是在每个worker中启动的线程,完成具体的任务task。
  • task则是一个任务实例,在executor中执行,一般来说与executor个数是一样的。

如何设置呢?
supervisor是你使用 ./storm supervisor 这个的命令启动的。
worker 则是你在storm.yaml中配置出来的,每个supervisor缺省会启4个,对应端口从6700-6703。
executor和task则是在topology中使用代码设置出来的。

builder.setSpout("a", new TestWordSpout(true), 16);builder.setSpout("b", new TestWordSpout(true), 16);builder.setBolt("c", new TestWordCounter(), 16)          .fieldsGrouping("a", new Fields("word"))          .fieldsGrouping("b", new Fields("word"));builder.setBolt("d", new TestGlobalCount())          .globalGrouping("a");Map conf = new HashMap();conf.put(Config.TOPOLOGY_WORKERS, 8);

来看一下,在setSpout/setBolt时,可以指定executor的个数,例如代码中都设为16个。而这个16表示总数,最后的conf中又指定worker为8个,8也是总数,与启动的supervisor有关,假如启动2个supervisor,则每个分配了4个,正好对应我们在yaml中的配置。然后,那16个executor会被分配到这8个worker中,每个worket启动2个executor来跑任务。

【补充】看上去executor与task是一一对应的,事实上可以通过代码配置。

builder.setSpout("csv-scanner", new RabbitMQScanSpout(pname)).setNumTasks(16);

这里是说这个spout会有16个task,如果它有8个executor,那么,每个executor则要承担2个task了。

其实上面的描述在UI中是可以很直观的看到。

这里写图片描述
Supervisors就是我们启动的工作节点个数,用了两台服务器各部署1个,计2个。
Used Slots/Free solts 在我们的yaml中配置了每个节点开4个端口,所以总数是8 。
这里写图片描述
data-mine是我的topology。
使用了8个worker,73个executor(73个task)。
这里写图片描述
分解到spout/bolt来看,1个spout使用了1个executor。
9个bolt,每个是8个executor,所以8*9+1=73个。
这里写图片描述
从这张图我们可以看到executor的分布情况,被均匀分配在各个supervisor的worker里了。
进一步,我们也可以从UI上看到每个bolt的压力及数据流,很直观。
这里写图片描述

以上仅仅是自己学习的笔记。


【补充二】上面的描述,我自己也觉得很乱,整理一下,关于并行度那几个数值的设置:

第一步,全局的,通过配置完成的,有两个:supervisor和worker。
你找两个机器,部署好apache storm,各自启动1个supervisor,这样,就有了2个supervisor。
然后,修改它们各自的storm.yaml,如下语句表示每个supervisor开4个slot,并且设置对应的端口,这里的slot数量就是跑的worker数量,这样,我们总共得到的worker是8个(2 * 4 =8):

 supervisor.slots.ports:    - 6700    - 6701    - 6702    - 6703     

第二步,topology使用的,用代码设置的,也有两个 executor和task。
首先要设置一下,我们使用几个worker,缺省是1个。如下代码让我们将第一步配置出的8个worker都用上,少了这一句会导致有7个slot是free的状态。

conf.setNumWorkers(8);

在setSpout/setBolt函数中,可以设置每个闪电或龙卷风的executor个数,比如

builder.setBolt("mongo-complain-day", new MongoRecordBolt(),16).shuffleGrouping("complain-day");

这里的16个executor会被storm环境分配到前面设置好的4个worker里,这样每个worker就被分配了4个executor。
还有一个task,修改上一句代码如下:

builder.setBolt("mongo-complain-day", new MongoRecordBolt(),16).setNumTasks(32).shuffleGrouping("complain-day");

于是,我们设置了32个task,这32个task会被分配到16个executor里,每个executor负责2个,而每个worker同样负责4个executor,每个supervisor负责4个worker,我们在整个storm中放了2个supervisor。

OK了,可以去StormUI中一一查看我们的配置数值。

0 0
原创粉丝点击