如何控制Apache Storm中Spout的数量及单机器实例部署数?
Apache Storm中Spout实例的控制方法
一、控制Spout总实例数
你说的没错,builder.setSpout的第三个参数就是用来设置Spout的总并行度(也就是实例总数)。比如你代码里的5,就会让拓扑启动5个Spout实例:
TopologyBuilder builder = new TopologyBuilder(); builder.setSpout("myspout", new MyDoSomethingOnTheHost(), 5);
这是Storm官方API提供的标准拓扑级实例数控制方式。
二、控制每台机器的Spout实例数(确保每台主机一个实例)
默认的Storm调度器(Default Scheduler)确实不会强制均匀分配实例,极端情况下所有实例都可能挤在同一台机器上。要实现每个主机恰好跑一个Spout实例,可以用这几种方案:
1. 硬绑定主机(固定集群场景适用)
如果你的集群主机列表是固定的,直接给每个Spout实例指定对应主机就行。比如集群有host1到host5五台机器:
TopologyBuilder builder = new TopologyBuilder(); // 定义Spout实例对应的主机列表 Map<String, List<String>> componentHosts = new HashMap<>(); componentHosts.put("myspout", Arrays.asList("host1", "host2", "host3", "host4", "host5")); builder.setSpout("myspout", new MyDoSomethingOnTheHost(), 5); // 绑定Spout到指定主机 builder.setComponentHosts(componentHosts);
这种方式能100%保证每个主机只跑一个实例,但缺点是集群主机变动时,得修改代码重新提交拓扑。
2. 用标签+调度约束(灵活集群场景适用)
不想硬编码主机名的话,可以给主机打标签,再通过调度规则限制实例分配:
- 第一步:在集群每台目标主机的
storm.yaml里加标签:
给需要跑Spout的5台机器都加上这个标签。supervisor.scheduler.meta: tags: ["spout-node"] - 第二步:在拓扑配置里设置约束,指定Spout只能用带
spout-node标签的机器,且每台机器最多跑1个实例:
这种方式更灵活,集群主机变动时只需要调整标签配置,不用改拓扑代码。Config conf = new Config(); conf.put(Config.TOPOLOGY_COMPONENT_SPECS, ImmutableMap.of( "myspout", ComponentSpec.builder() .setNumExecutors(5) .setConstraints(ImmutableMap.of( "tag", "spout-node", "maxPerNode", 1 )) .build() ));
3. 自定义调度器(特殊场景适用)
如果以上两种方式都满足不了需求,可以自己实现Storm调度器。重写org.apache.storm.scheduler.IScheduler接口的schedule方法,在里面写自己的实例分配逻辑,确保每个Spout实例分到不同主机。不过这种方式复杂度较高,一般只在极端定制场景下用。
注意:不管用哪种方案,都得保证集群中可用的目标主机数量≥Spout总实例数,否则拓扑会调度失败。
内容的提问来源于stack exchange,提问作者Gereon Such
相关产品推荐
相关产品推荐

