我是Trident的新手。我正在编写一个从kafka读取数据的三叉戟拓扑。主题名称为' test'。我有本地kafka设置。我在当地创办了zookeeper,kafka。并创建了一个主题' test'在kafka中打开制作人并输入消息“Hello Kafka!”#。
我想阅读消息' Hello Kafka'来自'测试'主题使用三叉戟。
以下是我的代码。我得到空元组。
TridentTopology topology = new TridentTopology();
BrokerHosts brokerHosts = new ZkHosts("localhost:2181");
TridentKafkaConfig kafkaConfig = new TridentKafkaConfig(brokerHosts, "test");
kafkaConfig.scheme = new SchemeAsMultiScheme(new StringScheme());
kafkaConfig.bufferSizeBytes = 1024 * 1024 * 4;
kafkaConfig.fetchSizeBytes = 1024 * 1024 * 4;
kafkaConfig.forceFromStart = false;
OpaqueTridentKafkaSpout opaqueTridentKafkaSpout = new OpaqueTridentKafkaSpout(kafkaConfig);
topology.newStream("TestSpout", opaqueTridentKafkaSpout).parallelismHint(1)
.each(new Fields(), new TestFilter()).parallelismHint(1)
.each(new Fields(), new Utils.PrintFilter());
这是我的TestFilter类代码
public TestFilter()
{
//
}
@Override
public boolean isKeep(TridentTuple tuple) {
boolean isKeep=true;
System.out.println("TestFilter is called...");
if (tuple != null && tuple.getValues().size()>0) {
System.out.println("data from kafka ::: "+tuple.getValues());
}
return isKeep;
}
每当我在kafka制作人中输入“&test;' test'主题,第一个sysout被打印但它没有通过if循环。我只是收到消息' TestFilter被称为......'不仅仅是那个。
我希望将我生成的实际数据输入到' test'话题。怎么样?
答案 0 :(得分:1)
问题在于Stream.each的参数。该方法的javadoc的相关部分是:
each(Fields inputFields, Filter filter)
文档不太清楚,但语义是你应该使用 inputFields 参数指定过滤器使用的所有字段。
Storm会在输入元组上应用投影并将其转发到过滤器。
鉴于您没有指定任何输入字段,投影会导致空元组,从而导致过滤器内tuple.getValues().size()>0
条件失败。
值得一提的还有其他变体:
each(Fields inputFields, Function function, Fields functionFields)
each(Function function, Fields functionFields)
这些将在输入元组的投影上应用提供的函数,将生成的元组追加到原始输入元组,将新字段重命名为 functionFields (即投影)仅用于应用功能)。
特别是第二个版本相当于调用每个 inputFields 设置为null(或new Fields()
),并将导致一个空元组传递给 function