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

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

第四章 Spouts

在本章中,你会看到设计topology入口点(spout)的最常用的策略和怎样使得spouts容错。

可靠消息 versus不可靠消息

当设计topology的时候,一件要时刻记在脑中的重要事情是消息的可靠性。如果一个消息不能被处理,你需要决定对这条单独的消息该做什么,对于整个topology该做什么。例如,当处理银行存款时,不遗漏一条交易消息是重要的。但是如果你处理上百条的tweet消息来寻找一些统计指标的话,丢失了一条数据,你可以假设指标是非常准确的。

在storm中,根据每个topology的需求来确保消息的可靠性是开发者的职责。这其中包含一个权衡问题。一个可靠的topology必须处理丢失的消息,而这需要更多的资源。一个不是那么可靠的topology可能丢失一些消息,但是资源没那么密集。不论选择的可靠性策略是什么,storm都提供工具来实现它。

为了管理spout的可靠性,你可以发送时和元组一起发送一个消息ID(collector.emit(new Values(…),tupleId))。ack方法和fail方法在元组被成功处理和处理失败时分别被调用。只有当元组被所有的目标bolts和锚定的bolts处理完时,元组才被处理成功(在第五章中会了解到怎么为一个元组锚定一个bolt)。

元组处理失败当:

﹒collector.fail(tuple)被目标spout调用

﹒处理时间超出配置的超时时间

我们看一个示例。假设你在处理银行的交易,你有如下的需求:

﹒如果一个交易失败,重新发送消息。

﹒如果一个交易失败太多次,终止topology。

你将创建一个发送100个随机交易ID的spout和一个接受到的元组80%都处理失败的bolt(你可以在ch04-spout示例中找到完成的示例)。你将用Map实现的spout来发射交易消息元组,这样的话重发消息是很容易的。

public voidnextTuple(){

if(!toSend.isEmpty()){

for(Map.Entry<Integer,String>transactionEntry:toSend.entrySet()){

Integer transactionId =transactionEntry.getKey();

String transactionMessage =transactionEntry.getValue();

collector.emit(newValues(transactionMessage),transactionId);

}

toSend.clear();

}

}

如果仍有消息等待被发送,那么获取每个交易消息及它相关联的ID并且将它们作为一个元组发射,然后清空消息队列。调用map的clear是安全的,因为nextTuple,fail和ack是唯一修改map的方法并且它们在相同的线程中运行。

维护两个map来记录等待发送的交易消息和每个交易已经失败的次数。ack方法仅仅从每个列表中删除了交易消息。

public voidack(Object msgId) {

messages.remove(msgId);

failCounterMessages.remove(msgId);

}

fail方法决定是否重发交易消息或者当失败次数太多时终止topology。

当你在topology中使用all分组并且任何bolt的实例失败的时候,spout的fail方法也会被调用。

public voidfail(Object msgId) {

Integer transactionId = (Integer)msgId;

// Check the number of times the transaction has failed

Integer failures =transactionFailureCount.get(transactionId) +1;

if(fails>=MAX_FAILS){

// If the number of failures is too high, terminate thetopology

throw new RuntimeException("Error, transaction id ["+

transactionId+"] has had too many errors ["+failures+"]");

}

// If the number of failures is less than the maximum,save the number and re-send

the message

transactionFailureCount.put(transactionId,failures);

toSend.put(transactionId,messages.get(transactionId));

LOG.info("Re-sending message ["+msgId+"]");

}

首先,检查交易失败的次数。如果一个交易失败太多次,抛出一个RuntimeException来终止它所在的worker。否则,保存失败的次数并且将交易消息发到toSend队列,这样当nextTuple方法被调用时它会被重新发送。

storm结点不保存状态,所以如果你在内存中保存信息(就像在这个示例中)并且结点失败的话,你将丢失所有已保存的信息。

 

Storm是一个快速失败的系统。如果一个异常被抛出,topology会失败,但是storm将以一致的状态重新启动处理,这样它可以正确的恢复。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值