影响Storm性能的因素
1、worker和slot的关系是一一对应的,一个worker占用一个slot。计算集群worker和slot数量一般以每个服务器的CPU线程数来计算。
如上面的环境就是
worker、slot:144 (6个supervisor,每个supervisor 都是24线程的CPU,24*6=144)
2、spout并发数,也就是setSpout后面的参数10——builder.setSpout(“words”,newKafkaSpout(kafkaConfig),10);
这里我在测试的时候,是使用kafka和storm做数据传输,kafka有一个partition的机制,Spout线程数量根据kafka topic的partition数量来定义,一般是1:1的关系,就是当前topic的partition数量为18,则spout的线程数量可以设置为18。也可以稍微比这个数多,但是不能多太多;具体需要多少个kafka partition大伙可根据需求来做测试找到自己需要的数值
3、bolt的并发数——builder.setBolt(“words”,newKafkaBolt(),10);
bolt的并发数量,决定了处理掉效率,bolt并发度为1,面对大的数据量可能会很慢,bolt并发度过高,也不好,可能会照成资源浪费。
具体数值需测试决定
worker、executor、task之间的关系
Storm在集群上运行一个Topology时,主要通过以下3个实体来完成Topology的执行工作:
1. Worker(进程)
2. Executor(线程)
3. Task
下图简要描述了这3者之间的关系:
1个worker进程执行的是1个topology的子集(注:不会出现1个worker为多个topology服务)。1个worker进程会启动1个或多个executor线程来执行1个topology的component(spout或bolt)。因此,1个运行中的topology就是由集群中多台物理机上的多个worker进程组成的。反过来说,一个Worker里面不会运行属于不同的topology的执行任务。
executor是1个被worker进程启动的单独线程。每个executor只会运行1个topology的1个component(spout或bolt)的task(注:task可以是1个或多个,storm默认是1个component只生成1个task,executor线程里会在每次循环里顺序调用所有task实例)。
task是最终运行spout或bolt中代码的单元(注:1个task即为spout或bolt的1个实例,executor线程在执行期间会调用该task的nextTuple或execute方法)。topology启动后,1个component(spout或bolt)的task数目是固定不变的,但该component使用的executor线程数可以动态调整(例如:1个executor线程可以执行该component的1个或多个task实例)。这意味着,对于1个component存在这样的条件:#threads<=#tasks(即:线程数小于等于task数目)。默认情况下task的数目等于executor线程数目,即1个executor线程只运行1个task。
如何在代码中设置 (例子):
ComponentConfigurationDeclarer#setNumTasks()
这是一个简单的代码例子,展示了在实践中如何设置:
topologyBuilder.setBolt("green-bolt", new GreenBolt(), 2)
.setNumTasks(4).shuffleGrouping("blue-spout);
在上面的代码中我们配置了Storm运行GreenBolt指定了初始有2个executor和4个关连的task。Storm会在每个 executor(线程)2个task。如果你不想显式的配置task的数量,Storm会默认的为每个executor运行1个task。
一个运行中的拓扑的例子
这个拓扑包含了3个组件:1个spout叫做BlueSpout,2个bolt分别叫 GreenBolt和YellowBolt。BlueSpout发送它的输出到GreenBolt,GreenBolt又把它的输出发到 YellowBolt。
简要分析:
3个组件的并发度加起来是10,就是说拓扑一共有10个executor,一共有2个worker,每个worker产生10 / 2 = 5条线程。
绿色的bolt配置成2个executor和4个task。为此每个executor为这个bolt运行2个task。
下面的代码配置了这3个组件,相关代码如下:
Config conf = new Config();
conf.setNumWorkers(2); // 使用2个worker进程
topologyBuilder.setSpout(“blue-spout”, new BlueSpout(), 2); // parallelism hint为2
topologyBuilder.setBolt(“green-bolt”, new GreenBolt(), 2) .setNumTasks(4) .shuffleGrouping(“blue-spout”);
topologyBuilder.setBolt(“yellow-bolt”, new YellowBolt(), 6) .shuffleGrouping(“green-bolt”);
StormSubmitter.submitTopology( “mytopology”, conf, topologyBuilder.createTopology() );
And of course Storm comes with additional configuration settings to control the parallelism of a topology, including:
此外还有其他的配置来控制拓扑的并发度,包括了:
TOPOLOGY_MAX_TASK_PARALLELISM: 这个设置指定了1个单独的组件的executor的数量的上限。当在测试阶段使用本地模式运行1个拓扑时,用来限制生成的线程的数量。你可以像下面这样来使用:
Config#setMaxTaskParallelism().
conf.setNumWorkers(workers); //设置worker数量
uilder.setBolt("2", new WordSpliter(),4) //设置Executor并发数量
builder.setBolt("2", new WordSpliter(),4).setNumTasks(1); //设置每个线程处理的Task数量
- Topology的worker数通过config设置,即执行该topology的worker(java)进程数。它可以通过storm rebalance 命令任意调整。
- Topology中某个bolt的executor数,即parallelismNum,即执行该bolt的线程数,在setBolt时由第三个参数指定。它可以通过storm rebalance 命令调整,但最大不能超过该bolt的task数;
- bolt的task数,通过setNumTasks()设置。(也可不设置,默认取bolt的executor数),无法在运行时调整。
- Bolt实例数,这个比较特别,它和task数相等。有多少个task就会new
多少个Bolt对象。而这些Bolt对象在运行时由Bolt的thread进行调度。也即是说builder.setBolt(“cpp”, new CppBolt(), 3).setNumTasks(5).noneGrouping(pre_name);
会创建3个线程,但有内存中会5个CppBolt对象,三个线程调度5个对象。
怎么样在运行过程中修改一个topology的并发度
Storm支持在不restart topology的情况下, 动态的改变(增减)worker processes的数目和executors的数目, 称为rebalancing.
主要有两种方法可以rebalance一个topology:
1、使用Storm web UI 来 rebalance topology.
2、使用CLI 工具 rebalance topology,一个例子如下:
#Reconfigure the topology “mytopology” to use 5 worker processes,
# the spout “blue-spout” to use 3 executors and
# the bolt “yellow-bolt” to use 10 executors.
storm rebalance mytopology -n 5 -e blue-spout=3 -e yellow-bolt=10