- 1、本文档共9页,可阅读全部内容。
- 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
- 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
Storm消息可靠的性的保障机制
Storm消息可靠性的保障机制
以WordCountToPology为例:
// 构造Topology
TopologyBuilder builder = new TopologyBuilder();
builder.setSpout(SPOUT_ID,new SentenceSpout(), 2)// 指定 Spout ,2 指的是使用2个executor来运行spout
.setNumTasks(4);//指定tasks的数量
// 指定 SentenceSpout 向SplitBolt发射tuple 随机分组
builder.setBolt(SPLIT_BOLT, new SplitBolt(), 3) // 3 指的就是使用3个executor来执行bolt
.shuffleGrouping(SPOUT_ID);
builder.setBolt(COUNT_BOLT, new CountBolt(), 2).fieldsGrouping(SPLIT_BOLT, new Fields(word));
builder.setBolt(PRINT_BOLT, new PrintBolt(), 1).globalGrouping(COUNT_BOLT); // 全局分组
这个topology从一个队列中读取句子,然后将句子分解成若干个单词,然后将它每个单词和该单词的数量发送出去。这种情况下,从 spout 中发出的 tuple 就会产生很多基于它创建的新 tuple:包括句子中单词的 tuple 和 每个单词的个数的 tuple。这些消息构成了这样一棵树:
如果这棵 tuple 树发送完成,并且树中的每一条消息都得到了正确的处理,就表明发送 tuple 的 spout 已经得到了“完整性处理”。对应的,如果在指定的超时时间内 tuple 树中有消息没有完成处理就意味着这个 tuple 失败了。这个超时时间可以使用 Config.TOPOLOGY_MESSAGE_TIMEOUT_SECS 参数在构造topology时进行配置,如果不配置,则默认时间为 30 秒。
在消息得到完整性处理后或者处理失败后会发生什么
为了理解这个问题,让我们先了解一下 tuple 的生命周期。下面是定义 spout 的接口(可以在 Javadoc 中查看更多细节信息):
public interface ISpout extends Serializable {
void open(Map var1, TopologyContext var2, SpoutOutputCollector var3);
void close();
void activate();
void deactivate();
void nextTuple();
void ack(Object var1);
void fail(Object var1);
}
首先,通过调用 Spout 的 nextTuple 方法,Storm 向 Spout 请求一个 tuple。Spout 会使用 open 方法中提供的SpoutOutputCollector 向它的一个输出数据流中发送一个 tuple。在发送 tuple 的时候,Spout 会提供一个 “消息 id”,这个 id 会在后续过程中用于识别 tuple。
使用 Storm 的可靠性机制的时候你需要注意两件事:首先,在 tuple 树中创建新节点连接时务必通知 Storm;其次,在每个 tuple 处理结束的时候也必须向 Storm 发出通知。通过这两个操作,Storm 就能够检测到 tuple 树会在何时完成处理,并适时地调用 ack 或者 fail 方法。Storm 的 API 提供了一种非常精确的方式来实现着两个操作
因此SentenceSpout需要做如下修改,在nextTuple方法中,发送tuple时,增加一个msgId;如果返回确认成功,则调用ack方法,把执行成功的msgId从缓存中移除,如果超时,或者异常,在调用fail方法,进行重试。具体实现如下:
public class SentenceSpout extends BaseRichSpout{
private static final Logger logger = LoggerFactory.getLogger(SentenceSpout.class);
/**
* tuple发射器
*/
pr
文档评论(0)