在简单的聚合风暴拓扑中分组

时间:2013-06-04 18:19:08

标签: java apache-storm

我正在尝试编写执行以下操作的拓扑:

  1. 订阅Twitter订阅源的订阅源(基于关键字)
  2. 汇总螺栓,汇集集合中的许多推文(比如说N),然后发送打印机螺栓
  3. 一个简单的螺栓,可以立即将集合打印到控制台。
  4. 实际上我想对集合进行更多处理。

    我在本地进行了测试,看起来它正在运行。但是,我不确定我是否正确设置了螺栓上的分组,以及在部署在实际风暴群上时这是否可以正常工作。如果有人可以帮助审查此拓扑并建议任何错误,更改或改进,我将不胜感激。

    感谢。

    这就是我的拓扑结构。

    builder.setSpout("spout", new TwitterFilterSpout("pittsburgh"));
       builder.setBolt("sampleaggregate", new SampleAggregatorBolt())
                    .shuffleGrouping("spout");
       builder.setBolt("printaggreator",new PrinterBolt()).shuffleGrouping("sampleaggregate");
    

    聚合螺栓

    public class SampleAggregatorBolt implements IRichBolt {
    
        protected OutputCollector collector;
        protected Tuple currentTuple;
        protected Logger log;
        /**
         * Holds the messages in the bolt till you are ready to send them out
         */
        protected List<Status> statusCache;
    
        @Override
        public void prepare(Map stormConf, TopologyContext context,
                            OutputCollector collector) {
            this.collector = collector;
    
            log = Logger.getLogger(getClass().getName());
            statusCache = new ArrayList<Status>();
        }
    
        @Override
        public void execute(Tuple tuple) {
            currentTuple = tuple;
    
            Status currentStatus = null;
            try {
                currentStatus = (Status) tuple.getValue(0);
            } catch (ClassCastException e) {
            }
            if (currentStatus != null) {
    
                //add it to the status cache
                statusCache.add(currentStatus);
                collector.ack(tuple);
    
    
                //check the size of the status cache and pass it to the next stage if you have enough messages to emit
                if (statusCache.size() > 10) {
                    collector.emit(new Values(statusCache));
                }
    
            }
        }
    
        @Override
        public void cleanup() {
    
    
        }
    
        @Override
        public void declareOutputFields(OutputFieldsDeclarer declarer) {
            declarer.declare(new Fields("tweets"));
    
        }
    
        @Override
        public Map<String, Object> getComponentConfiguration() {
            return null;  //To change body of implemented methods use File | Settings | File Templates.
        }
    
    
        protected void setupNonSerializableAttributes() {
    
        }
    
    }
    

    打印机螺栓

    public class PrinterBolt extends BaseBasicBolt {
    
        @Override
        public void execute(Tuple tuple, BasicOutputCollector collector) {
            System.out.println(tuple.size() + " "  + tuple);
        }
    
        @Override
        public void declareOutputFields(OutputFieldsDeclarer ofd) {
        }
    
    }
    

2 个答案:

答案 0 :(得分:4)

从我看来它看起来不错。但是,细节中的魔鬼。我不确定你的聚合器螺栓是做什么的,但如果它对传递给它的值做出任何假设,那么你应该考虑适当的字段分组。当您使用默认并行度提示1时,这可能不会产生很大的差异,但是如果您决定使用多个聚合螺栓实例进行缩放,则您可能会调用隐式逻辑假设来进行非随机分组。

答案 1 :(得分:0)

您一旦尝试订阅多个关键字,就会遇到问题。我建议你的鲸鱼喷水也会发出用于过滤的原始关键字。

然后我会做一个fieldsGrouping

而不是shuffleGrouping
builder.setBolt("sampleaggregate", new SampleAggregatorBolt())
            .shuffleGrouping("spout", new Fields("keyword"));

这样,您可以确保单个关键字的结果每次都在同一个螺栓上。这样您就可以正确计算聚合。如果省略fieldsGrouping Storm可以实例化任何数量的聚合螺栓,并将任何来自喷口的消息发送到聚合螺栓的任何实例,最终会导致错误的结果。

相关问题