storm入门到精通PDF文件百度云下载 - ag环亚娱乐
最新软件| 手机版| 软件专题 storm入门到精通PDF文件百度云下载
您的位置:ag环亚娱乐>软件频道 > 科学技术 > 大数据 > storm入门到精通PDF文件百度云下载
storm入门到精通PDF文件百度云下载

storm入门到精通PDF文件百度云下载

  • 软件大小:586MB
  • 软件语言:简体中文
  • 软件类型:国产软件
  • 软件类别:大数据
  • 更新时间:2017-12-29 23:26
  • 软件授权:免费版
  • 运行环境:xp/win7/win8/win10
  • 软件位数:64位/32位
  • 官方网站:
  • 软件等级:3星

586MB

同类推荐软件

软件介绍

为您推荐: storm入门到精通storm

storm到底是什么,可能有许多同学不是很了解,事实上它是一款开源分布式的大数据处理框架系统,此书已经经过翻译,其中必有各种不足请诸位读者朋友不吝斧正。这本书被业界称为实时版Hadoop。 随着越来越多的场景对Hadoop的MapReduce高延迟无法容忍,比如网站统计、推荐系统、预警系统、金融系统(高频交易、股票)等等, 大数据实时处理解决方案(流计算)的应用日趋广泛,目前已是分布式技术领域最新爆发点,而Storm更是流计算技术中的佼佼者和主流。 按照storm作者的说法,Storm对于实时计算的意义类似于Hadoop对于批处理的意义。Hadoop提供了map、reduce原语,使我们的批处理程序变得简单和高效。 同样,Storm也为实时计算提供了一些简单高效的原语,而且Storm的Trident是基于Storm原语更高级的抽象框架,类似于基于Hadoop的Pig框架, 让开发更加便利和高效。本课程会深入、全面的讲解Storm,并穿插企业场景实战讲述Storm的运用。 淘宝双11的大屏幕实时监控效果冲击了整个IT界,业界为之惊叹的同时更是引起对该技术的探索。 学完本课程你可以自己开发升级版的淘宝双11系统哦,大家赶紧下载学习吧!

storm入门到精通PDF文件百度云下载

官方介绍

Storm为分布式实时计算提供了一组通用原语,可被用于“流处理”之中,实时处理消息并更新数据库。这是管理队列及工作者集群的另一种方式。 Storm也可被用于“连续计算”(continuous computation),对数据流做连续查询,在计算时就将结果以流的形式输出给用户。它还可被用于“分布式RPC”,以并行的方式运行昂贵的运算。

译完此书之后,我已经忘记了是如何知道的Storm这个工具了。本人读过的所有技术书籍大部分都是在地铁上完成的,现在已经成了习惯。最近发现自己有一阵子没有看书,那个时候大数据已经相当火热,我就想找一些讲大数据分析的书来读一读,虽然一直没有机会接触大数据的工作,不过做一些技术储备也是好的。于是上谷歌和亚马逊用“大数据”、“实时分析”这类关键词搜索相关的技术文章和书籍。然后就知道了Storm,可惜一直没有找到中文的相关内容,只找到这一本《Getting Started with Storm》。可惜本人英文词汇量实在太少,书买来之后一直束之高阁,后来突发奇想我为什么不利用业余时间把这本书翻译了呢?于是由本人完成的《Getting Started with Storm》在并发编程网面世了。在本人之前已有人在CSDN上完成了本书除附录以外的全部翻译,并且有了PDF版。不过既然已经开始就不忍中途放弃了,所以一直坚持把本书译完。再次感谢并发编程网的朋友们的支持。

由于本人是持学习的目的翻译本书,对Storm的了解并不丰富,许多专用术语翻译难免不准确,如有谬误还请读者朋友们不吝指正。

本书基于最新的Storm0.7.1 版本撰写,从Storm开发环境的搭建、Storm工程的组成,到Storm各组件功能与开发,一步步的让读者入门并熟练掌握如何基于Storm的开发并利用Storm完成。本书共分为八个章节和三个附录:

第一章介绍Storm的特性以及可能的应用场景。

第二章讲述了Storm的运行模式,Storm工程包含的组件,以及如何创建一个Storm工程。

第三章对Storm的拓扑结构,各个组件如何分工协作做了详细介绍,数据流分组是本章重点。

第四章介绍Storm的数据源——spouts,Storm的所有数据都从这里开始。

第五章介绍Storm处理数据的组件。

第六章以一个简单的WEB应用讲解如何Storm进行数据分析。

第七章以PHP为例讲述如何使用非JVM语言开发Storm工程。

第八章讲解支持事务的拓扑,当然不要把这里的事务跟关系型数据库的事务等同起来。

附录A安装Storm客户端,以及常用命令。

附录B安装与部署Storm集群。

附录C如何运行第六章的例子

主要内容

storm有一个很重要的消息机制---确保spout发出的每个消息都会被完整的处理,本节将阐述storm是如何保证消息完整性和可靠性。

TopologyBuilder builder = new TopologyBuilder();

builder.setSpout("sentences", new KestrelSpout("kestrel.backtype.com",

22133,

"sentence_queue",

new StringScheme()));

builder.setBolt("split", new SplitSentence(), 10)

.shuffleGrouping("sentences");

builder.setBolt("count", new wordCount(), 20)

.fieldsGrouping("split", new Fields("word"));

上面的topology从Kestrel queue读取句子,将这些句子划分成词组,然后按照前面划分词组时统计的每个词的次数发送每个词。离开spout的某个tuple可能会触发创建很多基于它的tuples:句子中每个单词都会对应一个tuple,同时每个单词的次数也会对应一个tuple。消息的树状结构如下所示:

当元组树已经耗尽并且树中的每个消息都已被处理时,Storm认为元组从“完全处理”的一个元组中脱离。 当其树的消息未能在指定的超时内完全处理时,元组被认为失败。 可以使Config.TOPOLOGY_MESSAGE_TIMEOUT_SECS配置在特定于拓扑的基础上配置此超时,默认值为30秒。

[plain] view plain copy print?

public interface ISpout extendsSerializable {

voidopen(Map conf, TopologyContext context,SpoutOutputCollector collector);

voidclose();

voidnextTuple();

voidack(Object msgId);

voidfail(Object msgId);

}

当消息完整处理或失败时发生了什么

为了理解这个问题,让我们来看看一个元组从一个出口的生命周期。作为参考,这里是spouts实现的接口(有关更多信息,请参阅Javadoc):

[java] view plain copy print?

public interface ISpout extends Serializable {

void open(Map conf, TopologyContext context, SpoutOutputCollector collector);

void close();

void nextTuple();

void ack(Object msgId);

void fail(Object msgId);

}

首先,Storm通过Spout的nextTuple方法从Spout申请一个tuple。在open方法中,Spout使用此方法提供SpoutOutputCollector去发射一个tuple到输出streams中去。当发射一个tuple时,Spout会提供一个“message id”,用来后面区分不同的tuple。例如, KestrelSpout从kestrel队列中读取消息,然后在发射时会将Kestrel为消息提供的id作为“message id”。发射一条消息到SpoutOutputCollector,如下所示:

[java] view plain copy print?

_collector.emit(newValues("field1", "field2", 3), msgId);

然后,这个tuple会发送到bolts,同时Storm会跟踪已被创建的消息树状图。如果Storm检测到一个tuple已被“fully processed”, Storm将会在发射这个tuple的Spout上调用ack方法,参数msgId就是这个Spout提供给Storm的“message id”。类似的,如果这个tuple超时了, Storm会调用Spout上调用fail方法。注意, 一个tuple只能被创建它的Spout task上进行acked或者faiLED。因此,即使一个Spout在集群上正在执行很多tasks,一个tuple也只能被创建它的task进行acked或failed,而其他的task则不行。

再次使用KestrelSpout作为例子,看一下Spout是怎样保证消息处理的。当KestrleSpout从Kestrel 队列中拿出消息后,它打开这个消息。这就意味着消息并不会真正被从队列取出,而是处于等待状态,它需要确认消息已经被完整处理。当处于挂起(等待)状态时,消息不会被发送到队列的其他消费者。此外,如果客户端断开连接,则将该客户端的所有待处理消息放回队列。当打开消息时,Kestrel向客户端提供消息的数据以及消息的唯一ID。当将元组发送到SpoutOutputCollector时,KestrelSpout使用该确切的id作为元组的“消息id”。稍后,当在KestrelSpout上调用ack或fail时,KestrelSpout向Kestrel发送一个ack或fail消息,消息id将消息从队列中取出或重新启动。

消息可靠性

为保证消息的可靠性,需要满足一下两个条件。

元组创建时通知storm 在Storm消息树(元组树)中添加一个子结点的操作叫做锚定(anchoring)。在应用程序发送一个新元组时候,Storm会在幕后做锚定。还是之前的流式计算单词个数的例子,请看如下的代码片段:

[java] view plain copy print?

public class SplitSentence extends BaseRichBolt {

OutputCollector _collector;

public void prepare(Map conf, TopologyContext context, OutputCollector collector){

_collector = collector;

}

public void execute(Tuple tuple) {

String sentence = tuple.getString(0);

for(String word: sentence.split(" ")) {

_collector.emit(tuple, new Values(word));

}

_collector.ack(tuple);

}

public void declareOutputFields(OutputFieldsDeclarer declarer) {

declarer.declare(new Fields("word"));

}

}

每个单词元组是通过把输入的元组作为emit函数中的第一个参数来做锚定的。通过锚定,Storm就能够得到元组之间的关联关系(输入元组触发了新的元组),继而构建出Spout元组触发的整个消息树。所以当下游处理失败时,就可以通知Spout当前消息树根节点的Spout元组处理失败,让Spout重新处理。相反,如果在emit的时候没有指定输入的元组,叫做不锚定:

[java] view plain copy print?

_collector.emit(new Values(word));

像上面这样发射单词元组,会导致这个元组不被锚定(unanchored),这样Storm就不能得到这个元组的消息树,继而不能跟踪消息树是否被完整处理。这样下游处理失败,不能通知到上游的Spout任务。不同的应用的有不同的容错处理方式,有时候需要这样不锚定的场景。

一个输出的元组可以被锚定到多个输入元组上,叫做多锚定(multi-anchoring)。这在做流的合并或者聚合的时候非常有用。一个多锚定的元组处理失败,会导致Spout上重新处理对应的多个输入元组。多锚定是通过指定一个多个输入元组的列表而不是单个元组来完成的。例如:

[java] view plain copy print?

List anchors = new ArrayList();

anchors.add(tuple1);

anchors.add(tuple2);

_collector.emit(anchors, new Values(word));

多锚定会把这个新输出的元组添加到多棵消息树上。注意多锚定可能会打破消息的树形结构,变成有向无环图(DAG),Storm的实现既支持树形结构,也支持有向无环图(DAG)。在本文中,提到的消息树跟有向无环图是等价的。消息之间的关系是有向无环图的例子见下图:

Spout元组A触发了B和C两个元组,而这两个元组作为输入,共同作用后触发D元组。

元组处理完毕后通知storm

锚定的作用就是指定元组树的结构--下一步是当元组树中某个元组已经处理完成时,通知Storm。通知是通过OutputCollector中的ack和fail函数来完成的。例如上面流式计算单词个数例子中的split Bolt的实现SplitSentence类,可以看到句子被切分成单词后,当所有的单词元组都被发射后,会确认(ack)输入的元组处理完成。

当前消息树的根元组处理失败了,可以利用OutputCollector的fail函数来立即通知Storm。例如,应用程序可能捕捉到了数据库客户端的一个异常,就显示地通知Storm输入元组处理失败。通过显示地通知Storm元组处理失败,这个Spout元组就不用等待超时而能更快地被重新处理。

Storm需要占用内存来跟踪每个元组,所以每个被处理的元组都必须被确认。因为如果不对每个元组进行确认,任务最终会耗光可用的内存。

做聚合或者合并操作的Bolt可能会延迟确认一个元组,直到根据一堆元组计算出了一个结果后,才会确认。聚合或者合并操作的Bolt,通常也会对他们的输出元组进行多锚定。

Storm以一种有效的方式实现可靠性

acker任务

一个Storm拓扑有一组特殊的"acker"任务,它们负责跟踪由每个Spout元组触发的消息的处理状态。当一个"acker"看到一个Spout元组产生的有向无环图中的消息被完全处理,就通知当初创建这个Spout元组的Spout任务,这个元组被成功处理。可以通过拓扑配置项Config.TOPOLOGY_ACKER_EXECUTORS来设置一个拓扑中acker任务executor的数量。Storm默认TOPOLOGY_ACKER_EXECUTORS和拓扑中配置的Worker的数量相同(关于executor和Worker的介绍,参见理解Storm并发一文)--对于需要处理大量消息的拓扑来说,需要增大acker executor的数量。

元组的生命周期

理解Storm的可靠性实现方式的最好方法是查看元组的生命周期和元组构成的有向无环图。当拓扑的Spout或者Bolt中创建一个元组时,都会被赋予一个随机的64比特的标识(message id)。acker任务使用这些id来跟踪每个Spout元组产生的有向无环图的处理状态。在Bolt中产生一个新的元组时,会从锚定的一个或多个输入元组中拷贝所有Spout元组的message-id,所以每个元组都携带了自己所在元组树的根节点Spout元组的message-id。当确认一个元组处理成功了,Storm就会给对应的acker任务发送特定的消息--通知acker当前这个Spout元组产生的消息树中某个消息处理完了,而且这个特定消息在消息树中又产生了一个新消息(新消息锚定的输入是这个特定的消息)。

举个例子,假设"D"元组和"E"元组是基于“C”元组产生的,那么下图描述了确认“C”元组成功处理后,元组树的变化。图中虚线框表示的元组代表已经在消息树上被删除了:

当“C”从树中移除时,同一时刻,“D”和“E”会加到树中。树永远不能过早的结束。

正如上面已经提到的,在一个拓扑中,可以有任意数量的acker任务。这导致了如下的两个问题:

1、当拓扑中的一个元组确认被处理完,或者产生一个新的元组时,Storm应该通知哪个acker任务?

2、通知了acker任务后,acker任务如何通知到对应的Spout任务?

Storm采用对元组中携带的Spout元组message-id哈希取模的方法来把一个元组映射到一个acker任务上(所以同一个消息树里的所有消息都会映射到同一个acker任务)。因为每个元组携带了自己所处的元组树中根节点Spout元组(可能有多个)的标识,所以Storm就能决定通知哪个acker任务。

当一个Spout任务产出一个新的元组,仅需要简单的发送一个消息给对应的acker(Spout元组message-id哈希取模)来告知Spout的任务标示(task id),以此来通知acker当前这个Spout任务负责这个消息。当acker看到一个消息树被完全处理完,它就能根据处理的元组中携带的Spout元组message-id来确定产生这个Spout元组的task id,然后通知这个Spout任务消息树处理完成(调用 Spout任务的ack函数)。

实现细节

对于拥有上万节点(或者更多)的巨大的元组树,跟踪所有的元组树会耗尽acker使用的内存。acker任务不显示地(记录完整的树型结构)跟踪元组树,相反它使用了一种每个Spout元组只占用固定大小空间(大约20字节)的策略。这个跟踪算法是Storm工作的关键,而且是重大突破之一。

一个acker任务存储了从一个Spout元组message-id到一对值的映射关系spout-message-id-->。第一个值是创建了这个Spout元组的任务id,用来后续处理完成时通知到这个Spout任务。第二个值是一个64比特的叫做“ack val”的数值。它是简单的把消息树中所有被创建或者被确认的元组message-id异或起来的值。每个消息创建和被确认处理后都会异或到"ack val"上,A xor A = 0,所以当一个“ack val”变成了0,说明整个元组树都完全被处理了。无论是很大的还是很小的元组树,"ack val"值都代表了整个元组树中消息的处理状态。由于元组message-id是随机的64比特的整数,所以同一个元组树中不同元组message-id发生撞车的可能性特别小,因此“ack val”意外的变成0的可能性非常小。如果真的发生了这种情况,而恰好这个元组也处理失败了,那仅仅会导致这个元组的数据丢失。

使用异或操作来跟踪消息树处理状态的想法非常有才。因为消息的数量可能有成千上万条,每个都单独跟踪(读者可以思考下怎么搞)是非常低效而且不可水平扩展的。而且采用异或的方式后,就不依赖于acker接收到消息的顺序了。

搞明白了可靠性的算法,让我们看看所有失败的场景下Storm如何避免数据丢失:

Bolt任务挂掉:导致一个元组没有被确认,这种场景下,这个元组所在的消息树中的根节点Spout元组会超时并被重新处理

acker任务挂掉:这种场景下,这个acker挂掉时正在跟踪的所有的Spout元组都会超时并被重新处理

Spout任务挂掉:这种场景下,需要应用自己实现检查点机制,记录当前Spout成功处理的进度,当Spout任务挂掉之后重启时,继续从当前检查点处理,这样就能重新处理失败的那些元组了。

调整可靠性

acker任务是轻量级的,所以在一个拓扑中不需要太多的acker任务。可以通过Storm UI(id为"__acker"的组件)来观察acker任务的性能。如果吞吐量看起来不正常,就需要添加更多的acker任务。

去掉可靠性

如果可靠性无关紧要--例如你不关心元组失败场景下的消息丢失--那么你可以通过不跟踪元组的处理过程来提高性能。不跟踪一个元组树会让传递的消息数量减半,因为正常情况下,元组树中的每个元组都会有一个确认消息。另外,这也能减少每个元组需要存储的id的数量(指每个元组存储的Spout message-id),减少了带宽的使用。

有三种方法来去掉可靠性:

设置Config.TOPOLOGY_ACKERS为0。这种情况下,Storm会在Spout吐出一个元组后立马调用Spout的ack函数。这个元组树不会被跟踪。

当产生一个新元组调用emit函数的时候通过忽略消息message-id参数来关闭这个元组的跟踪机制。

如果你不关心某一类特定的元组处理失败的情况,可以在调用emit的时候不要使用锚定。由于它们没有被锚定到某个Spout元组上,所以当它们没有被成功处理,不会导致Spout元组处理失败。

storm入门到精通百度云内容预览

storm入门到精通PDF文件百度云下载

  • 下载地址

用户评论

(您的评论需要经过审核才能显示)