可以对kafka喷口发出的元组进行字段分组吗?如果是,那么Storm如何知道Kafka记录中的字段?
答案 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 中,declareOutputFields
为 implemented,如下所示:
@Override
public void declareOutputFields(OutputFieldsDeclarer declarer) {
RecordTranslator<K, V> translator = kafkaSpoutConfig.getTranslator();
for (String stream : translator.streams()) {
declarer.declareStream(stream, translator.getFieldsFor(stream));
}
}
它从 RecordTranslator
接口获取字段,其实例从 kafkaSpoutConfig
即 KafkaSpoutConfig<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"));