我是Storm的新手,我正在使用项目storm-starter开始使用Storm。在这个项目中有一个名为WordCountTopology
的拓扑,构建拓扑的关键代码是:
builder.setBolt("split", new SplitSentence(), 8).shuffleGrouping("spout");
builder.setBolt("count", new WordCount(), 12).fieldsGrouping("split", new Fields("word"));
并且在WordCount bolt的实现中,关键方法execute
是:
@Override
public void execute(Tuple tuple, BasicOutputCollector collector) {
String word = tuple.getString(0);
Integer count = counts.get(word);
if (count == null)
count = 0;
count++;
counts.put(word, count);
collector.emit(new Values(word, count));
}
我的问题是:
由于字段分组的功能是:具有相同字段word
的元组将转到相同的任务进行后期处理。这里的“任务”意味着线程,我该如何证明这个功能呢?另外,在我看来,方法execute
中的逻辑有点尴尬。在单个任务中,参数tuple
始终相同,但在execute
方法中它并未反映这一点,换句话说,逻辑不会使用此方便。
execute
中的代码未考虑归档分组的功能,此处的代码也可以应用于随机分组的情况。
答案 0 :(得分:2)
我想提出几点意见,这可能有助于明确你的疑虑
这里“任务”意味着线程
在storm的术语中,任务是NOT
个线程,但它们负责处理实际逻辑。 您在代码中实现的每个spout或bolt都会在整个群集中执行任意数量的任务。因此,您可以将它们定义为组件的运行实例,即Spouts或Bolts。
还有另一个名为Executors
的实体,它是负责运行这些任务的线程。它可以运行同一组件的一个或多个任务。具有多个任务的执行程序实际上是说执行程序多次执行相同的组件。
现在回到你的问题
执行中的代码不考虑归档分组的功能,此处的代码也可以应用于随机分组的情况
在非常简短的A fields grouping lets you group a stream by a subset of its fields
中,意思是为了进行字数统计,如果我们使用字段名称'first_name`上的fieldsGrouping过滤流,那么期望所有带有值的first_name字段说( Foo)应该执行相同的任务,并且具有不同值(Bar)的相同字段将转到另一个任务。
所以这里execute
方法应该接收相同的字段值,因此可以轻松更新其计数器,并且这样做不需要考虑任何特殊的。记住整个逻辑,记住螺栓将被链接到适当的数据,这就是为什么使用正确的分组变得如此重要。因此,如果您使用shuffleGrouping
,则会运行相同的代码,但会生成不正确的数据。
答案 1 :(得分:1)
Well Pinky(或其他任何认为有用的人),证明它,你只需要跟踪螺栓或喷口任务ID:
@Override
public void prepare(Map map, TopologyContext tc, OutputCollector oc) {
this.boltId = tc.getThisTaskId();
}
现在在接收元组的相同fieldsGrouped bolt的execute()中,你只需打印id和元组:
@Override
public void execute(Tuple tuple) {
String myWord = (String) tuple.getValue(0);
System.out.println("word: "+myWord+" boltID:"+boltId);
}