1 storm并行度的概念
①当storm程序中某一个环节计算能力跟不上的时候,需要增加多个线程同时执行。由此引出并行度的概念
代码:
setBolt(String id, IRichBolt bolt, Number parallelism_hint);
注:如果不指定组件的并行度,默认是一个线程执行。
2 storm的分组概念(Stream Grouping)
说明:Stream Grouping定义一个流在Bolt任务间如何被切分。
Storm提供了6个Stream Grouping类型:
①Shuffle Grouping:随机分组,随机分发tuple到bolt的任务,保证每个任务获得相等数量的tuple;
②Fields Grouping:按字段分组,根据指定字段分割数据流,并分组。例如根据"user_id"字段,相同"user_id"的tuple会被分配到相同的Bolts里的一个task,而不同的"user_id"tuple则会被分配到不同的Bolts里的task;
③All Grouping:广播发送,对于每一个tuple,所有的bolts都会接受到。这种类型需要谨慎使用;
④Global Grouping:全局分组,tuple会被分配到storm中的一个Bolt的其中一个task,就是分配给id值最低的那个task;
⑤Non Grouping:不分组,stream不关心到底谁会收到它的tuple,目前这种分组和shuffle grouping是一样的效果,有一点不同的是storm会把这个bolt放到这个bolt的订阅者同一个线程里面去执行
⑥Direct Grouping:直接分组,这是一种比较特殊的分组方法,用这种分组意味着消息的发送者需要指定消息接受者的哪个task处理消息。只有声明为Direct Stream消息流可以声明这种分组方式。而且这种tuple必须使用emitDirect来发送。消息处理者可以通过TopologyContext来获取它的消息task的id(OutputCollector.emit方法会返回task的id),storm内部acker使用这种分组策略;
代码:
builder.setBolt("split_bolt", new SplitBolt()).shuffleGrouping("word_count_spout");
builder.setBolt("count_and_print_bolt", new CountAndPrintBolt()).shuffleGrouping("split_bolt");
2.1 Local or Shuffle Grouping
说明:如果目标bolt有一个或多个task在同一个工作进程中,tuple将会被随机分配到这些tasks.否则和普通的shuffle grouping的效果行为一致;
说明:1、如果storm程序中的并行度总数太多,放在一个jvm中运行比较缓慢;
2、每个jvm都有spout和逻辑执行线程
3、为了减少JVM之间数据传输的开销,设计一个数据分离策略,如果数据分发没有严格的业务含义,考虑spout或者上游的数据只能发给当前的JVM中的下游Bolt.
4、local是针对当前的jvm来讲的,shuffle是针对集群来说的
代码:如果一个storm topology任务想在多个jvm中运行,如何设置?
Config stormConf = new Config();
stormConf.setNumWorkers(workers);
注:如果不指定numberworks的数量,默认是在一个work中运行。
改变worker和并发度的代码:
package com.storm.wordcount;
import backtype.storm.Config;
import backtype.storm.LocalCluster;
import backtype.storm.StormSubmitter;
import backtype.storm.generated.AlreadyAliveException;
import backtype.storm.generated.InvalidTopologyException;
import backtype.storm.generated.StormTopology;
import backtype.storm.topology.TopologyBuilder;
public class WordCountTopologyDriver {
public static void main(String[] args) throws AlreadyAliveException, InvalidTopologyException {
// 1、准备任务信息
TopologyBuilder builder = new TopologyBuilder();
builder.setSpout("word_count_spout", new WordCountSpout(), 2);
builder.setBolt("split_bolt", new SplitBolt(), 4).shuffleGrouping("word_count_spout");
builder.setBolt("count_and_print_bolt", new CountAndPrintBolt(), 2).shuffleGrouping("split_bolt");
// 2、提交任务
Config stormConf = new Config();
stormConf.setNumWorkers(2);
StormTopology topology = builder.createTopology();
// 2.1提交本地模式
// LocalCluster localCluster = new LocalCluster();
// localCluster.submitTopology("wordcount", stormConf, topology);
// 2.2集群模式
StormSubmitter.submitTopology("wordcount-1", stormConf, topology);
}
}
2.1.1改变worker和并发度的现象对比
注:一般将多个并行度中的实例叫做task,默认情况下,一个bolt的并行度为4,代表了4个task。