您的位置:首页 > 其它

Storm的基本概念介绍

2015-11-19 20:08 405 查看
本文译自:http://storm.apache.org/documentation/Concepts.html

以下是Storm的主要概念和相关资源信息的连接:

1. Topologies(拓扑)

2. Streams(数据流)

3. Spouts(发送器)

4. Bolts(运算器)

5. Stream groupings(数据流分组)

6. Reliability(可靠性)

7. Tasks(任务)

8. Workers(工作者)

Topologies

一个实时应用的逻辑被打包到一个Strom的topology中。Storm的Topology类与MapReduce的Job。关键的差异是MapReduce的Job最后是要结束的,而Topology是持续运行的(直到人工终止它)。一个Topology就是一个用StreamGroupings连接的Spouts和Bolts的图表,这些概念会以下资源中介绍:

Ø 
TopologyBuilder:在Java中使用这个类来构建Topologies;

Ø 
在一个产品的集群上运行Topologies;

Ø 
本地模式:这里介绍如何在本地模式中开发和测试Topologies。

Streams

Stream是Strom中的核心抽象,一个Stream是一个要处理的无边界的数据单元序列,这些数据单元以并行的分布式的方式来创建。在Stream的数据单元内,以命名字段的模式来定义Stream。默认情况下,数据单元可以包含integer、long、short、byte、string、double、float、boolean,以及字节数组等类型的数据。还可以定义自己的序列器,以便在数据单元中能够自然的使用自定义类型。

在声明的时候,每个Steam都要设定一个id。因为单一Stream的Spout和Bolt是非常通用的,所以OutputFieldsDeclarer有方便的方法来声明单一Stream而不需指定id,这种情况中,相应的Stream会被设定一个默认的id:”default”。

Tuple:Stream是由tuple构成的。

OutputFieldsDeclarer:用于声明Stream和它们的模式。

串行化:有关Storm的动态tuple类型和自定义串行化的声明信息。

ISerialization:自定义的串行器必须实现这个接口。(这个接口定义说明的连接错误)

CONFIG.TOPOLOGY_SERIALIZATIONS:自定义的串行器可以使用这个配置来注册。

 

Spouts

在Topology中,Spout是Stream的入口。通常Spout会从外部资源中读取数据单元,并把这些数据单元放到Topology中(如Kestre队列或Twitter的API),Spout既可以是可靠的也是不可靠的。如果Storm处理失败,可靠的Spout会重复发送数据单元,而不可靠的Spout会丢弃已经发送过的数据单元。

Spout能够发送多个Stream。使用OutputFieldsDeclarer接口的declareStream方法就可以完成多个Stream的声明,并且把对应的Stream指定给发送数据单元时所使用的SpoutOutputCollector类的emit方法

Spout上的主要方法是nextTuple。它既可以把新的Tuple发送到Topology中,如果没有新的Tuple,它也可以简单 。对于任意的Spout的实现,nextTuple的非阻塞性是至关重要的,因此Storm会在同一个线程上调用所有的Spout方法。

在Spout上的其他主要方法是ack和fail。当Storm检测到Spout的发送处理成功或失败时会调用这两个方法,ack和fail方法只对可靠Spout有效,详细请看Javadoc

相关资源:

IRichSpout:Spout必须实现这个接口

消息处理的保障

 

Bolts

Topology中的所有处理都要在Bolt中完成。Bolt能够完成从过滤、功能、聚合、连接、会话到数据库等任何处理。

Bolt能够完成简单的流转换,复杂的流的转换经常需要过个步骤和多个Bolt。例如,把一个微博的流转换为一个趋势图片的流至少需要两个步骤:1.一个Bolt用来滚动统计每个图片的计数;2.一个或多个Bolt输出最上层的图片(使用3个Bolt来做这个转换更具可扩展性)。

Bolt也能够发送多个Stream。使用OutputFieldsDeclarer接口的declareStream方法就可以完成多个Stream的声明,并且把对应的Stream指定给发送数据单元时所使用的SpoutOutputCollector类的emit方法

声明一个Bolt的输入流时,就要订阅另一个组件所指定的流。如果要订阅另一个组件的所有的流,就必须单独的订阅每个流。InputDeclarer有非常友好的语法用于订阅在默认的流id上声明的流。declarer.shuffleGrouping(“1”)订阅了组件”1”上的默认流,它等同于declarer.shuffleGrouping(“1”,DEFAULT_STREAM_ID)。

Bolt中的主要方法是execute方法,它需要一个新的Tuple(数据单元)作为输入。Bolt使用OutputCollector对象来发送新的Tuple,对于每个要处理的Tuple,Bolt都要调用OutputCollector上的ack方法,以便Storm知道Tuple处理完成的时机(这样最终可以判断它安全的应答了初始发送的Tuple)。对于处理输入Tuple的大多数场合,会基于这个输入的Tuple发送0或多个Tuple,然后再处理输入的Tuple,Storm提供了一个自动应答的IBasicBolt接口。

需要注意的是OutputCollector是非线程安全的,并且所有的发送、应答和失败都必须发生在同一个线程中,详细的细节请参照Troubleshooting

相关资源

IRichBolt:这是Bolt的一般性接口。

IBasicBolt:这是一个用于定义执行过滤或简单功能的Bolt的便利接口。

OutputCollector:Bolt使用这个类的一个实例把Tuple发送给输出流。

消息处理的保障.

 

Stream groupings

Topology定义的一部分就是要给每个Bolt指定要接收的输入流。数据流的分组定义了数据流应该如何分配到在Bolt的任务中。

在Storm中有8种内置的数据流分组,也可以通过实现CustomStreamGrouping接口来实现自定义流。

1. Shuffle groupings(随机分组):这是一种把Tuple随机分配给Bolt任务的方法,这种方法保证每个Bolt获得相同数量的tuple。

2. Fields groupings(字段分组):通过分组中的特定字段来分割数据流。例如,如果对应的数据流时通过”user-id”来分组的,那么带有相同”user-id”的Tuple总会被分配到相同的任务中,而带有不同”user-id”的Tuple可以分配到不同的任务中。

3. Partial Key groupings(部分的关键分组):跟Fieldsgroupings一样,通过分组中的特定字段来分割数据流,但是在输入的数据发生正态偏离的时候,它会在两个下游的Bolt之间来进行负载均衡,从而能够比较好的利用资源。它的工作方式和优势请阅读“这里

4. All groupings(全复制分组):把对应的数据流复制给所有相关的Bolt的任务。

5. Global groupings(全局分组):整个流会被路由到一个单一的Bolt任务中,具体的它会被路由到id最小的任务中。

6. None groupings:指定这种分组就不用关心对应的数据流是如何分组的。当前,这种分组方式等同于Shuffle分组。不过最终Strom会把这种分组的数据流推到下游的Bolt来执行,这类似于订阅Bolt或Spout的线程。

7. Direct groupings(指向型分组):这是一种特殊类型的分组,这种分组意味着Tuple的生产者决定了接收这个Tuple的消费者任务。只能够在声明了定向流的数据流上声明定向分组。定向流必须使用emitDirect方法之一来发送。Bolt通过使用TopologyContext或保持OutputCollector中的emit方法(它会返回发送Tuple的任务id)的输出轨迹来获取消费者的任务id。

8. Local or shuffle groupings(本地或随机分组):如果在相同的工作进程中目标Bolt有多个任务,那么Tuple只会被分组到这些任务中,否则跟普通的随机分组一样。

相关资源:

TopologyBuilder:这个类用于定义Topology

InputDeclarer:调用TopologyBuilder类的setBolt()方法时会返回这个对象,并通过这个对象来声明Bolt的输入流和输入流的分组方式。

CoordinateBolt:这种类型的Bolt对于分布式的Topology是有用的,并且大量的用于定向Stream和定向分组。(这个资源不可用)

 

Reliability(可靠性)

Storm保证每个Spout的元组被Topology完全的处理。这种保证机制是通过每个Spout的元组所触发的元组树的轨迹并判断元组树被成果执行完成的时机来实现的。每个Topology都会关联一个”超时消息”,如果Storm在超时前不能检测到Spout的元组已经执行完成,那么就会断定该元组执行失败,随后会重复执行它。

要利用Storm的可靠性能力,必须告诉Storm创建元组树内新的边界的时机,并且无论什么时候在一个独立的元组处理完成之后都要告诉Storm。使用用于Bolt发送元组的OutputCollector对象来完成这项任务。在emit方法中完成定位,并且要声明完成一个元组处理所要使用的ack方法。

更详细的信息请看“消息处理的保障”。

 

Tasks(任务)

每个Spout或Bolt的执行都可以作为很多跨集群的任务。每个任务对应一个执行的线程,并且Stream的分组定义了如何把数据元组从一组任务发送到另一组任务。在TopologyBuilder的setSpout和setBolt方法中给每个Spout和Bolt设置并行机制。

 

Workers(工作者)

Topology的执行会跨越一个或多个工作者进程。每个工作者进程就是一个物理JVM,并且要执行对应Topology的所有任务的一个子集。例如,如果联合的Topology的并行数是300,并且给这个Topology分配了50个工作者,那么每个工作者要执行6个任务(在工作者内部以线程方式工作)。Strom会尝试把所有任务均匀的分配给每个工作者。

相关资源:

Config.TOPOLOGY_WORKERS:这个配置用于设置分配给正在执行的Topology的工作者的数量。

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  框架 storm 技术