getting start with storm 翻译 第四章 part-2

转载请注明出处:http://blog.csdn.net/lonelytrooper/article/details/9965867

获取数据

这里你将看到一些常用的设计spouts的方法,它们可以从多个源有效的收集数据。

直接连接

在直接连接的架构中,spout直接连接到一个消息发射器(见图4-1)。


图4-1 直接连接的spout

这种架构实现简单,特别是当消息发射器是一个众所周知的设备或设备组时。一个众所周知的设备是指一个在启动时就被知晓并且在整个topology生命周期中都保持一致的设备。一个未知的设备是一个topology已经运行后添加的设备。一个众所周知的设备组是一个组中所有设备在启动时就被知晓的设备组。

作为一个示例,创建一个spout来使用Twitter Streaming API读取Twitter流。Spout将直接连接到作为消息发射器的API。通过过滤流来获取所有公共的与track参数(就像Twitter开发页面上的文档)相匹配的tweets。完整的示例可以在Twitter示例的github页面上找到。

Spout从配置对象中获取连接参数(track,user,andpassword)并且创建一个到API的连接(在这个示例中,使用Apache的DefaultHttpClient)。它从连接中每次读取行,将该行从JSON格式解析为java对象,然后发射它。

public void nextTuple(){

//Create the client call

client new DefaultHttpClient();

client.setCredentialsProvider(credentialProvider);

HttpGet get new HttpGet(STREAMING_API_URL+track);

HttpResponse response;

try {

//Execute

response client.execute(get);

StatusLine status response.getStatusLine();

if(status.getStatusCode() == 200){

InputStream inputStream response.getEntity().getContent();

BufferedReader reader new BufferedReader(new InputStreamReader(inputStream));

String in;

//Read line by line

while((in reader.readLine())!=null){

try{

//Parse and emit

Object json jsonParser.parse(in);

collector.emit(new Values(track,json));

}catch (ParseException e) {

LOG.error("Error parsing message from twitter",e);

}

}

}

catch (IOException e) {

LOG.error("Error in communication with twitter api ["+get.getURI().toString()+"],

sleeping 10s");

try {

Thread.sleep(10000);

catch (InterruptedException e1) {

}

}

}

这里你正在锁定nextTuple方法,所以你从未执行ack和fail方法。在实际的应用中,我们推荐你在一个单独的线程中加锁并且使用内部的队列来交换信息(你可以在34页的下一个示例”Enqueued Messages”中学到怎样做)。

这很好!

你使用一个单独的spout读取Twitter。如果你并行你的topology,你将有多个spouts来读取同一个流的不同部分,这没有意义。所以当你有多个流要读时你怎样并行你的处理呢?storm的一个有趣的特点是你可以从任何组件(spouts/bolts)访问TopologyContext。通过这个特性,你可以在你的spout实例之间划分流。

public void open(Map confTopologyContext context,

SpoutOutputCollector collector) {

//Get the spout size from the context

int spoutsSize =

context.getComponentTasks(context.getThisComponentId()).size();

//Get the id of this spout

int myIdx context.getThisTaskIndex();

String[] tracks =((Stringconf.get("track")).split(",");

StringBuffer tracksBuffer new StringBuffer();

for(int i=0itracks.length;i++){

//Check if this spout must read the track word

ifspoutsSize == myIdx){

tracksBuffer.append(",");

tracksBuffer.append(tracks[i]);

}

}

if(tracksBuffer.length() == 0) {

throw new RuntimeException("No track found for spout" +

" [spoutsSize:"+spoutsSize+",tracks:"+tracks.length+"] the amount" +

" of tracks must be more then the spoutparalellism");

this.track =tracksBuffer.substring(1).toString();

}

...

}

通过这种技术,你甚至可以在数据源间分布收集器。相同的技术可以被应用在其他的场景-例如,从web服务器收集日志文件。见图4-2。


图4-2 直接哈希连接

在前边的例子中,你连接spout到一个众所周知的设备。你可以使用相同的方法来连接到一个未知的设备并听过一个协同系统来维护设备列表。该协调器检测列表的变化并建立和销毁连接。例如,当从web服务器收集日志文件时,web服务器的列表可能随着时间变化。当一个web服务器被添加时,协调器检测到变化并为它建立一个新的spout。见图4-3。

推荐建立从spout到消息发射器的连接,而不是相反的方式。如果运行spout的集群挂掉了,storm会在别的机器上重新启动该spout,所以从spout来定位消息发射器比消息发射器保存spout所在的机器的路径简单。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值