风暴 - 有条件地从卡夫卡喷口消耗流?

时间:2015-07-23 16:18:04

标签: apache-kafka apache-storm

我有一个场景,我将json发布到Kafka实例。然后我使用Kafka Spout将流发射到螺栓上。

但是现在我想在我的json消息中添加额外的字段(称之为x)。如果xa,我希望它被boltA使用,如果xb我希望它被boltB使用。

有没有办法根据流内容将流引导到正确的螺栓?

1 个答案:

答案 0 :(得分:2)

最简单的方法应该是添加SplitBolt消耗KafkaSpout,评估字段x,然后转发到不同的输出流:

public class SplitBolt extends BaseRichBolt {
  OutputCollector collector;

  public void prepare(...) {
    this.collector = collector;
  }

  public void execute(Tuple input) {
    Object x = ... // get field x from input
    String streamId;
    if(x == a) {
      streamId = "stream-xa";
    } else { // x == b
      streamId = "stream-xb";
    }
    collector.emit(streamId, input, input.getValues());
  }

  public void declareOutputFields(OutputFieldsDeclarer declarer) {
    Fields schema = new Fields(...)
    declarer.declareStream("stream-xa", schema);
    declarer.declareStream("stream-xy", schema);
  }
}

在构建拓扑时,您将BoltA连接到“stream-xa”并将BoltB连接到“stream-xb”:

TopologyBuilder b = new TopologyBuilder();
b.setSpout("spout", new KafkaSpout(...));
b.setBolt("split", new SplitBolt()).shuffleGrouping("spout");
b.setBolt("boltA", new BoltA()).shuffleGrouping("split", "stream-xa");
b.setBolt("boltB", new BoltB()).shuffleGrouping("split", "stream-xb");

作为替代方案,也应该可以继承KafkaSpout并直接发送到两个不同的流。但是,代码更难以正确使用。