Kafka Spout的现场分组

时间:2014-09-25 14:50:19

标签: apache-storm apache-kafka

可以对kafka喷口发出的元组进行字段分组吗?如果是,那么Storm如何知道Kafka记录中的字段?

3 个答案:

答案 0 :(得分:2)

Storm中的字段分组(以及一般分组)用于螺栓,而不是用于喷嘴。这是通过InputDeclarer课程完成的 当您在setBolt()上致电TopologyBuilder时,会返回InputDeclarer

答案 1 :(得分:1)

Kafka Spout宣称其输出字段与其他任何组件一样。我的解释基于KafkaSpout的当前implementation

在KafkaSpout.java类中,我们看到了调用KafkaConfig Scheme的getOutputFields()方法的declareOutputFields方法。

@Override
public void declareOutputFields(OutputFieldsDeclarer declarer) {
    declarer.declare(_spoutConfig.scheme.getOutputFields());
}

默认情况下,KafkaConfig使用RawMultiScheme以这种方式实现此方法。

  @Override
  public Fields getOutputFields() {
    return new Fields("bytes");
  }

那是什么意思?,如果你声明使用fieldGrouping从KafkaSpout读取元组的bolt你知道包含等于字段“bytes”的每个元组将由同一个任务执行。如果要发出任何字段,则应根据需要实施新方案。

答案 2 :(得分:0)

TL:DR KafkaSpout 的默认实现在 declareOutputFields 中声明了以下输出字段:

new Fields("topic", "partition", "offset", "key", "value");

所以在构建拓扑代码时直接做:

topologyBuilder.setSpout(spoutName, mySpout, parallelismHintSpout);
topologyBuilder.setBolt(boltName, myBolt, parallelismHintBolt).fieldsGrouping(spoutName, new Fields("key"));

细节:稍微研究一下代码就会知道:

在 Kafka Spout 中,declareOutputFieldsimplemented,如下所示:

@Override
public void declareOutputFields(OutputFieldsDeclarer declarer) {
    RecordTranslator<K, V> translator = kafkaSpoutConfig.getTranslator();
    for (String stream : translator.streams()) {
        declarer.declareStream(stream, translator.getFieldsFor(stream));
    }
}

它从 RecordTranslator 接口获取字段,其实例从 kafkaSpoutConfigKafkaSpoutConfig<K, V> 获取。 KafkaSpoutConfig<K, V>CommonKafkaSpoutConfig 扩展(尽管在 1.1.1 版本中略有不同)。此 returns DefaultRecordTranslator 的构建器。如果您查看此类 implementation 中的字段,您会发现:

public static final Fields FIELDS = new Fields("topic", "partition", "offset", "key", "value");

所以我们可以在拓扑代码中的字段分组中直接使用Fields("key")

topologyBuilder.setBolt(boltName, myBolt, parallelismHintBolt).fieldsGrouping(spoutName, new Fields("key"));