我有一个简单的风暴拓扑,主要由两个螺栓组成:
BatchPricingRequestReaderBolt - 接受批量请求并为批次中的每个单独定价请求发出元组。
PricingRequestHandlerBolt - 对定价请求进行评估。
我有一个BatchPricingRequestReaderBolt和四个PricingRequestHandlerBolts。
在BatchPricingRequestReaderBolt上将PricingRequestHandlerBolt添加为shuffleGrouping。
在我的批处理请求有四个定价请求的情况下,我希望所有四个PricingRequestHandlerBolts同时运行 - 每个处理一个元组。然而,这不是我观察到的。有时它的工作方式类似,但大部分时间它只使用三个或两个PricingRequestHandlerBolts。
我错过了一些明显的东西吗?
编辑:这是一些演示问题的简单代码。我希望所有四个元组能够在同一时间处理,但这不是大部分时间都会发生的事情。
import org.apache.storm.Config;
import org.apache.storm.LocalCluster;
import org.apache.storm.generated.StormTopology;
import org.apache.storm.spout.SpoutOutputCollector;
import org.apache.storm.task.OutputCollector;
import org.apache.storm.task.TopologyContext;
import org.apache.storm.topology.OutputFieldsDeclarer;
import org.apache.storm.topology.TopologyBuilder;
import org.apache.storm.topology.base.BaseRichBolt;
import org.apache.storm.topology.base.BaseRichSpout;
import org.apache.storm.tuple.Fields;
import org.apache.storm.tuple.Tuple;
import org.apache.storm.tuple.Values;
import java.util.Map;
public class SimpleStormTest {
public static void main(String[] args) {
TopologyBuilder builder = new TopologyBuilder();
builder.setSpout("TestSpout", new TestSpout(), 1);
builder.setBolt("TestBolt", new TestBolt(), 4)
.shuffleGrouping("TestSpout");
StormTopology topology = builder.createTopology();
Config conf = new Config();
conf.setNumWorkers(5);
LocalCluster cluster = new LocalCluster();
cluster.submitTopology("LocalTopology", conf, topology);
}
public static class TestSpout extends BaseRichSpout {
private transient SpoutOutputCollector collector;
int counter = 0;
@Override
public void open(Map conf, TopologyContext context, SpoutOutputCollector collector) {
System.out.println("%%% open " + Thread.currentThread().getName());
this.collector = collector;
}
@Override
public void nextTuple() {
System.out.println("nextTuple");
try {
Thread.sleep(10_000);
int valueToEmit = counter;
counter++;
collector.emit(new Values(valueToEmit));
collector.emit(new Values(valueToEmit));
collector.emit(new Values(valueToEmit));
collector.emit(new Values(valueToEmit));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
@Override
public void declareOutputFields(OutputFieldsDeclarer declarer) {
declarer.declare(new Fields("Input"));
}
}
public static class TestBolt extends BaseRichBolt {
private transient OutputCollector collector;
@Override
public void prepare(Map stormConf, TopologyContext context, OutputCollector collector) {
this.collector = collector;
}
@Override
public void execute(Tuple input) {
System.out.println("!!! Executing " + Thread.currentThread().getName());
try {
Thread.sleep(2000);
collector.emit(new Values(input.getValueByField("Input")));
collector.ack(input);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
@Override
public void declareOutputFields(OutputFieldsDeclarer declarer) {
declarer.declare(new Fields("Result"));
}
}
}
我希望我不理解一些基本概念,否则这将是一个非常严重的问题。
编辑2:我现在已经编写了自己的分组,其行为正如我所期望的那样,但我认为这是一个常见的用例,必须有一些我根本无法得到的基础。