FW:分布式实时计算storm 原理…

本文介绍了Apache Storm中的基本拓扑结构,包括Spout和Bolt的实现方式,以及如何通过TopologyBuilder定义数据流的传递路径。同时展示了ExclamationTopology示例,演示了如何将单词与特定字符串拼接。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

http://my.oschina.net/leejun2005/blog/147607?from=20130804

6、一个简单的Topology

让我们来看一个简单的topology的例子, 我们看一下storm-starter里面的ExclamationTopology:

    TopologyBuilder builder =newTopologyBuilder();

    builder.setSpout(1,newTestWordSpout(),10);

    builder.setBolt(2,newExclamationBolt(),3)

           .shuffleGrouping(1);

    builder.setBolt(3,newExclamationBolt(),2)

           .shuffleGrouping(2);

这个Topology包含一个Spout和两个Bolt。Spout发射单词, 每个bolt在每个单词后面加个”!!!”。这三个节点被排成一条线: spout发射单词给第一个bolt, 第一个bolt然后把处理好的单词发射给第二个bolt。如果spout发射的单词是["bob"]和["john"], 那么第二个bolt会发射["bolt!!!!!!"]和["john!!!!!!"]出来。

我们使用setSpout和setBolt来定义Topology里面的节点。这些方法接收我们指定的一个id, 一个包含处理逻辑的对象(spout或者bolt), 以及你所需要的并行度。

这个包含处理的对象如果是spout那么要实现IRichSpout的接口, 如果是bolt,那么就要实现IRichBolt接口.
最后一个指定并行度的参数是可选的。它表示集群里面需要多少个thread来一起执行这个节点。如果你忽略它那么storm会分配一个线程来执行这个节点。

setBolt方法返回一个InputDeclarer对象, 这个对象是用来定义Bolt的输入。 这里第一个Bolt声明它要读取spout所发射的所有的tuple — 使用shuffle grouping。而第二个bolt声明它读取第一个bolt所发射的tuple。shuffle grouping表示所有的tuple会被随机的分发给bolt的所有task。给task分发tuple的策略有很多种,后面会介绍。

如果你想第二个bolt读取spout和第一个bolt所发射的所有的tuple, 那么你应该这样定义第二个bolt:

1 builder.setBolt(3,newExclamationBolt(),5)
2             .shuffleGrouping(1)
3             .shuffleGrouping(2);

让我们深入地看一下这个topology里面的spout和bolt是怎么实现的。Spout负责发射新的tuple到这个topology里面来。TestWordSpout从["nathan", "mike", "jackson", "golda", "bertels"]里面随机选择一个单词发射出来。TestWordSpout里面的nextTuple()方法是这样定义的:

1 publicvoidnextTuple() {
2     Utils.sleep(100);
3     finalString[] words =newString[] {"nathan","mike",
4                      "jackson","golda","bertels"};
5     finalRandom rand =newRandom();
6     finalString word = words[rand.nextInt(words.length)];
7     _collector.emit(newValues(word));
8 }

可以看到,实现很简单。

ExclamationBolt把”!!!”拼接到输入tuple后面。我们来看下ExclamationBolt的完整实现。

01 publicstaticclassExclamationBoltimplementsIRichBolt {
02     OutputCollector _collector;
03   
04     publicvoidprepare(Map conf, TopologyContext context,
05                         OutputCollector collector) {
06         _collector = collector;
07     }
08   
09     publicvoidexecute(Tuple tuple) {
10         _collector.emit(tuple,newValues(tuple.getString(0) +"!!!"));
11         _collector.ack(tuple);
12     }
13   
14     publicvoidcleanup() {
15     }
16   
17     publicvoiddeclareOutputFields(OutputFieldsDeclarer declarer) {
18         declarer.declare(newFields("word"));
19     }
20 }

prepare方法提供给bolt一个Outputcollector用来发射tuple。Bolt可以在任何时候发射tuple — 在prepare, execute或者cleanup方法里面, 或者甚至在另一个线程里面异步发射。这里prepare方法只是简单地把OutputCollector作为一个类字段保存下来给后面execute方法使用。

execute方法从bolt的一个输入接收tuple(一个bolt可能有多个输入源). ExclamationBolt获取tuple的第一个字段,加上”!!!”之后再发射出去。如果一个bolt有多个输入源,你可以通过调用Tuple#getSourceComponent方法来知道它是来自哪个输入源的。

execute方法里面还有其它一些事情值得一提: 输入tuple被作为emit方法的第一个参数,并且输入tuple在最后一行被ack。这些呢都是Storm可靠性API的一部分,后面会解释。

cleanup方法在bolt被关闭的时候调用, 它应该清理所有被打开的资源。但是集群不保证这个方法一定会被执行。比如执行task的机器down掉了,那么根本就没有办法来调用那个方法。cleanup设计的时候是被用来在local mode的时候才被调用(也就是说在一个进程里面模拟整个storm集群), 并且你想在关闭一些topology的时候避免资源泄漏。

最后,declareOutputFields定义一个叫做”word”的字段的tuple。

以local mode运行ExclamationTopology
让我们看看怎么以local mode运行ExclamationToplogy。

storm的运行有两种模式: 本地模式和分布式模式. 在本地模式中, storm用一个进程里面的线程来模拟所有的spout和bolt. 本地模式对开发和测试来说比较有用。 你运行storm-starter里面的topology的时候它们就是以本地模式运行的, 你可以看到topology里面的每一个组件在发射什么消息。

在分布式模式下, storm由一堆机器组成。当你提交topology给master的时候, 你同时也把topology的代码提交了。master负责分发你的代码并且负责给你的topolgoy分配工作进程。如果一个工作进程挂掉了, master节点会把认为重新分配到其它节点。关于如何在一个集群上面运行topology, 你可以看看Running topologies on a production cluster文章。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值