Storm shuffle分组不均匀分布

时间:2018-01-09 16:50:25

标签: java apache-storm

我有一个简单的风暴拓扑,主要由两个螺栓组成:

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:我现在已经编写了自己的分组,其行为正如我所期望的那样,但我认为这是一个常见的用例,必须有一些我根本无法得到的基础。

0 个答案:

没有答案