实际上就是用多线程。没有真的对集群做扩容。
官网介绍
http://storm.apache.org/releases/1.1.2/Understanding-the-parallelism-of-a-Storm-topology.html
storm中运行topology的实体主要有三个:
worker processes: 一个supervisor可以启多个worker。一个topology可以运行在一个worker或者接worker中。每个worker运行一个topology的子集。一个worker进程只服务于一个指定的topology。
executors(threads): 一个worker进程上可以运行多个executor。
tasks: task实际上是storm里面最小的运算单元,执行实际的数据处理。 一个executors上可以运行多个相同组件(spout、bolt)的task。每个spout、bolt可以作为多个task在集群中被处理。
对于一个组件(spout、bolt)在它的生命周期中,task的数量时不变的,executor的数量可变。这意味着,线程(executor)的数量可能小于等于task的数量。默认情况下task的数量等于executor的数量。
默认情况下:
1个supervisor节点启动4个worker进程。
每一个topology默认占用一个worker进程。
每个worker会启动executor。
每个executor默认启动一个task。
(这里用单机版storm演示。即解压storm.tar后 ,什么配置文件都不用改,只用加个环境变量就行了。
运行作业:提交作业到storm服务器上运行
查看UI会发现。只启动了一个work来执行我们的clusterSumStormTopology作业。
我们的storm作业只有一个spout和一个bolt,但是在默认情况下却启动了3个executor。因为其中有一个是acker。
设置介绍
源码中的defaults.yaml配置文件<storm.yaml<topology代码中指定的配置<内部配置<外部配置
worker processes数量设置(设置运行某个具体的topology使用几个worker,而不是一个supervisor启动几个worker。一个supervisor启动几个worker的设置是修改storm.yaml配置文件,给supervisor.slots.ports添加几个端口。)
代码中配置:
修改之前的代码mian中的config部分
public static void main (String[] args){
try {
//TopologyBuilder根据spout和bolt来构建Topology
//storm中任何一个作业都是通过Topology方式进行提交的
//Topology中需要指定spout和bolt的执行顺序
TopologyBuilder tb = new TopologyBuilder();
tb.setSpout("DataSourceSpout", new DataSourceSpout());
//SumBolt以随机分组的方式从DataSourceSpout中接收数据
tb.setBolt("SumBolt", new SumBolt()).shuffleGrouping("DataSourceSpout");
Config config = new Config();
//设置让集群启动2个worker来执行这个作业
config.setNumWorkers(2);
//把执行acker的executor关掉
config.setNumAckers(0);
//代码提交到storm集群上运行
StormSubmitter.submitTopology("ClusterSumStormTopology", config, tb.createTopology());
} catch (AlreadyAliveException e) {
e.printStackTrace();
} catch (InvalidTopologyException e) {
e.printStackTrace();
} catch (AuthorizationException e) {
e.printStackTrace();
}
}
重新打包,上传到nimbus所在节点,关闭原来运行的ClusterSumStormTopology作业,重新运行。
重新查看UI。这时就只启动了2个executor(因为这个topology程序只有一个spout和一个bolt,我们把acker关掉了。这里只是做个测试,生产中不要关掉acker,不然不能保证数据有且只有一次被执行,很可能数据被重复发送,或者漏了。)
用了2个worker来执行这个topology(我们在代码中设置的2)。
executor数量设置
public static void main (String[] args){
try {
//TopologyBuilder根据spout和bolt来构建Topology
//storm中任何一个作业都是通过Topology方式进行提交的
//Topology中需要指定spout和bolt的执行顺序
TopologyBuilder tb = new TopologyBuilder();
//第三个参数2,是并行度,是这个组件有几个executor来执行
tb.setSpout("DataSourceSpout", new DataSourceSpout(),2);
//SumBolt以随机分组的方式从DataSourceSpout中接收数据
//第三个参数2,是并行度,是这个组件有几个executor来执行
tb.setBolt("SumBolt", new SumBolt(),2).shuffleGrouping("DataSourceSpout");
Config config = new Config();
//设置让集群启动2个worker来执行这个作业
config.setNumWorkers(2);
//把执行acker的executor关掉。默认情况下有几个worker就有几个acker
config.setNumAckers(0);
//代码提交到storm集群上运行
StormSubmitter.submitTopology("ClusterSumStormTopology", config, tb.createTopology());
} catch (AlreadyAliveException e) {
e.printStackTrace();
} catch (InvalidTopologyException e) {
e.printStackTrace();
} catch (AuthorizationException e) {
e.printStackTrace();
}
}
task数量设置
public static void main (String[] args){
try {
//TopologyBuilder根据spout和bolt来构建Topology
//storm中任何一个作业都是通过Topology方式进行提交的
//Topology中需要指定spout和bolt的执行顺序
TopologyBuilder tb = new TopologyBuilder();
//第三个参数2,是并行度,是这个组件有几个executor来执行
tb.setSpout("DataSourceSpout", new DataSourceSpout(),2);
//SumBolt以随机分组的方式从DataSourceSpout中接收数据
//第三个参数2,是并行度,是这个组件有几个executor来执行
tb.setBolt("SumBolt", new SumBolt(),2)
.setNumTasks(4)//设置task数量为4.这个bolt有2个executor,4个task
.shuffleGrouping("DataSourceSpout");
Config config = new Config();
//设置让集群启动2个worker来执行这个作业
config.setNumWorkers(2);
//把执行acker的executor关掉。默认情况下有几个worker就有几个acker。
config.setNumAckers(0);
//代码提交到storm集群上运行
StormSubmitter.submitTopology("ClusterSumStormTopology", config, tb.createTopology());
} catch (AlreadyAliveException e) {
e.printStackTrace();
} catch (InvalidTopologyException e) {
e.printStackTrace();
} catch (AuthorizationException e) {
e.printStackTrace();
}
}
topology在运行中可以动态调整worker和executor的数量,并不需要重启集群。
1.在storm的UI上调整。
2.使用客户端工具来调整。