我有一个场景,我将json发布到Kafka实例。然后我使用Kafka Spout将流发射到螺栓上。
但是现在我想在我的json消息中添加额外的字段(称之为x
)。如果x
是a
,我希望它被boltA使用,如果x
是b
我希望它被boltB使用。
有没有办法根据流内容将流引导到正确的螺栓?
答案 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
并直接发送到两个不同的流。但是,代码更难以正确使用。