核心概念

Apache Storm从一端读取实时数据的原始流,并通过一系列小处理单元传递它,并在另一端输出处理过的有用的信息。下图描述了Apache Storm的核心概念。

 image.png


现在让我们仔细看看Apache Storm的组件:

 

组件

描述

Tuple

TupleStorm中的主要数据结构。 它是有序元素的列表。 默认情况下,Tuple支持所有数据类型。 通常,它被建模为一组用逗号分隔开并传递给Storm集群的值。

Stream

StreamStorm中的核心抽象。一个Stream由无限的Tuple序列组成,这些元组会被分布式并行地创建和处理。通过StreamTuple包含的字段名称来定义这个Stream
  每个Stream声明时都被赋予了一个ID。只有一个流的SpoutBolt非常常见,所以OutputFieldsDeclarer提供了不需要指定ID来声明一个Stream的方法(SpoutBolt都需要声明输出的Stream)。这种情况下,StreamID是默认的“default”

 

Spout

Stream的来源。 一般来说,Storm接受来自原始数据源的输入数据,例如Twitter Streaming APIApache Kafka队列,Kestrel队列等。另外,您可以写Spout以从数据源读取数据。 ISpout”是实现Spout的核心接口,一些特定的接口是IRichSpoutBaseRichSpoutKafkaSpout等。

Bolt

Bolt是逻辑处理单元。 Spouts将数据传递到Bolt然后Bolt处理这些数据并生成新的输出流。 Bolt可以执行过滤(filtering),聚合(aggregation),连接(joining),与数据源和数据库进行交互(interacting)的操作。 Bolt接收数据并发射到一个或多个其他的Bolt IBolt”是实现Bolt的核心接口。 一些常见的接口是IRichBoltIBasicBolt等。

  

我们来看一个“Twitter分析”的实时示例,看看它如何在Apache Storm中建模。下图描述了结构:

 image.png

Twitter Analysis”的输入来自Twitter Streaming API Spout将使用Twitter Streaming API读取用户的推文,并将其输出为Tuple流。 来自Spout的每个Tupletwitter用户名和一个推文作为值并用逗号分开。 然后,这组Tuple将被转发给BoltBolt把推文分成单独的单词,计算单词数量,并将信息保存到指定的数据源中。 现在,我们可以通过查询数据源轻松获得结果。

1.Topology 

SpoutsBolts连接在一起,形成一个Topology,实时应用程序逻辑在这个Storm Topology中指定。 简而言之,一个Topology是一个有向图,其顶点是计算,边是数据流。一个简单的Topology开始于SpoutsSpout将数据发送到一个或多个Bolts Bolt表示Topology中具有最小处理逻辑的节点,并且Bolt的输出可以作为输入发射到另一Bolt中。Storm将一直运行Topology,直到用户终止它。 Apache Storm的主要工作是运行Topology,并在给定的时间运行任意数量的Topology

2.Task

SpoutBolt Topology中最小的逻辑单元,一个Topology是使用一个Spout和一组Bolt构建的。 SpoutBolt应该以特定的顺序正确执行,以便Topology成功运行。 Storm中对每个SpoutBolt的执行称为“任务”。 简单来说,一个任务就是执行一个Spout或者一个Bolt 在给定时间内,每个SpoutBolt都可以有多个实例在多个单独的线程中运行。

3.Worker

Topology在多个工作节点(Worker)上以分布式方式运行。 Storm将任务平均分配在所有的工作节点上。 工作节点的角色是监听作业,并在新作业到达时启动或停止进程。

4.Stream Grouping

数据流从Spouts流向 Bolts或从一个Bolt流向另一个Bolt 流分组(Stream grouping)控制TupleTopology中的前进路径,并帮助我们理解TupleTopology中的传输。 如下所述,Storm中有八种内置分组。你也可以通过实现CustomStreamGrouping接口来自定义一个流分组策略。

a). Shuffle Grouping

在随机分组中,相同数量的元组随机分布在所有执行BoltWorker中。 下图描述了随机分组的场景。

image.png

b). Field Grouping

Tuple中相同值的字段被组合在一起,剩下的Tuple留在外面。 然后,将具有相同字段值的Tuple发送给执行Bolt的同一个Worker 例如,如果流按字段“word”分组,则具有相同字符串“Hello”的Tuple将移至同一个Worker 下图显示了Field Grouping的工作原理。

image.png

c). Globle Grouping 

所有的流可以分组并转发给一个Bolt 此分组将源的所有实例生成的Tuple发送到单个目标实例(具体来说,选择ID最小的Worker)。

image.png

d). All Grouping

All Grouping将每个Tuple的单个副本发送到接收Bolt的所有实例。 这种分组被用于向Bolt发送信号。 All Grouping对于连接(join)操作都很有用。

image.png

e). Partial Key Grouping 

Field Grouping一样,流也是用指定的分组字段进行分组的,但是在多个下游Bolt之间是有负载均衡的,这样当输入数据有倾斜时可以更好的利用资源。这篇论文很好的解释了这是如何工作的,有哪些优势。 

f). None Grouping 

即不用关心流是如何分组的,目前None Grouping等价于Shuffle Grouping

g). Direct Grouping 

一种特殊的分组。对于这样分组的流,Tuple的生产者决定消费者的哪个任务会接收处理这个Tuple。只能在声明做直连的流(direct streams)上声明Direct groupings分组方式。只能通过使用org.apache.storm.task.OutputCollector.java类里的

emitDirect方法来发射Tuple给直连流。一个Bolt可以通过提供的TopologyContext来获得消费者的任务ID,也可以通过OutputCollector对象的emit函数(会返回Tuple被发送到的任务的ID)来跟踪消费者的任务ID。在ack的实现中,Spout有两个直连输入流,ackackFail,使用了这种直连分组的方式。

h). Local or shuffle grouping 

如果目标Bolt在同一个worker进程里有一个或多个任务,Tuple就会通过洗牌(Shuffle)的方式被分配到这些同一个进程内的任务里。否则,就跟普通的洗牌分组(Shuffle Grouping)一样。这种方式的好处是可以提高Topology的处理效率,因为worker内部通信就是进程内部通信了,相比Topology之间的进程间通信要高效的多。worker进程间通信是通过使用Netty来进行网络通信的。                                                                                                               

5. Reliability(可靠性) 

Storm保证了TopologySpout产生的每个Tuple都会被处理,Storm是通过跟踪每个Spout所产生的所有Tuple构成的树形结构并得知这棵树何时被完整地处理来达到可靠性。每个Topology对这些树形结构都有一个关联的消息超时设置,如果在这个超时时间里Storm检测到Spout产生的一个Tuple没有被成功处理完,那这个Tuple就被认为处理失败了,后续会重新处理一遍。

 

为了发挥Storm的可靠性,需要你在创建一个Tuple树中的一条边时告诉Storm,也需要在处理完每个Tuple之后告诉Storm。这些都是通过Bolt发射Tuple数据用的OutputCollector对象来完成的。标记(anchoring)在emit方法里完成,处理完一个Tuple后需要使用ack方法来告诉Storm



关注微信服务号,手机看文章
关注微信服务号,手机看文章