源地址:http://storm.apache.org/documentation/Concepts.html
本文介绍了storm的主要概念,并且给出相关链接供你查看更多信息。本文讨论的概念如下所示:
1、Topologies
2、Streams
3、Spouts
4、Bolts
5、Stream Grouping
6、Reliability
7、Tasks
8、Workers
Topologies
实时应用的逻辑将打包成Storm的topology。 Storm topology类似于MapReduce job。关键的不同点在于: MapReduce job最终会结束,然而topology会永久运行(除非你杀死它)。topology是spouts和bolts组成的图谱,其中spouts和bolts由stream grouping方式链接。这些概念将在下面介绍。
资料:
l TopologyBuilder:在Java中使用这个类可以构造topologies
l 在生产集群上运行topologies。
l 本地模式:怎样在本地模式下开发测试topologies。
Streams
stream是Storm的核心抽象。stream是tuples组成的无边界的序列,其中tuple可以以分布式的方式并行的产生和处理。 Streams定义模式是:在stream tuples中命名一些域。默认情况下, tuples可以包含integers、longs、shorts、bytes、doubles、floats、booleans以及byte arrays。当然,也可以定义客户自己的序列,这样客户自己定义的新类型就可以在tuples中使用。
每一个stream在声明时就会给与一个id。因为single-stream spouts和bolts比较常用,因此OutputFieldsDeclarer 有比较方便的方法,在不指定id的条件下就可以声明single stream。这种情况下, stream的id是默认的“default”。
资料:
l Tuple: streams是由tuples组成的
l OutputFieldsDeclarer:用来声明流以及它们的机制
l Serialization: 有关Storm 动态类型的tuples的信息以及声明客户序列的信息
l Iserialization: 客户的序列必须实现这个接口
l CONFIG.TOPOLOGY_SERIALIZATIONS:客户可以使用这项配置选项注册自己的序列
Spouts
spout是topology的数据流来源。 一般来说, spouts从外部数据源读取tuples,然后将它们发射到topology(例如, Kestrel队列或者TwitterAPI)。 Spouts可以是可靠的,也可以是不可靠的。可靠的spouts能够在storm处理tuple失败时重新处理它,而不可靠的spout一旦发射tuples就不再关心它了。
spouts可以发射不止一个数据流。 要发射多个流, 就需要使用OutputFieldsDeclarer类的declareStream方法声明多个streams, 然后还需要使用SpoutOutputCollector类的emit方法指定待发射的数据流。
spouts主要的方法是nextTuple。 nextTuple或者是向topology发射新tuple,或者是在没有新tuples需要发送的时候简单的返回。 必要的是: nextTuple不能阻塞任何spout的实现,因为Storm使用相同的线程调用spout方法。(一旦某个spout方法被nextTuple被阻塞,那次线程也就被阻塞,同样storm不能使用该线程调用其他spout方法)。
spouts其他主要方法是ack和fail。 它们是在storm检测所发射的tuple是否完整发送时调用。ack和fail只能由可靠的spouts调用。可以查看Javadoc获取更多有关信息。
资料:
l IRichSpout:这是spouts必须实现的接口
l 保证消息处理机制
Bolts
topologies中的所有数据处理是在bolts中完成的。 Bolts可以处理多种来源的数据:过滤后的数据、函数返回的数据、聚合后数据、合并后数据、与数据库交互产生的数据等等。
Bolts可以做简单的数据流转换。 复杂的数据流转换通常要求多个步骤以及多个bolts。 例如, 将tweets的数据流转成某个热点图像的数据流至少需要两步: 一个bolts来做每幅图片被tweets反复引用的总数; 另外, 需要一个或多个bolts输出最热点的图像(对于这个指定流转换,如果采用更加可伸缩的方式,则可以使用三个botls而不是两个)。
Bolts可以发射不止一个stream。 要想做到发射多个流, 需要使用OutputFieldsDeclarer类的declareStream方法声明多个流, 然后还需要使用OUtputCollector类的emit方法指定待发射的流。
当声明bolts输入streams时,通常需要使用另一个组件订阅某些特定的流。如果你想使用这个组件订阅所有流,你需要分别订阅每个流。InputDeclarer有语法糖结构,这个结构可以用来订阅以默认stream id声明的streams。即: declarer.shuffleGrouping("1")订阅组件“1”上的默认stream, 这和使用declarer.shuffleGrouping("1",DEFAULT_STREAM_ID)一样。
bolts的主要方法是execute方法,用来输入新tuple。 bolts使用OutputCollector对象发射新tuples。 当bolts处理的每个tuple完整输入时,需要调用OutputCollector类的ack方法来通知Storm(它最终可以确认原始的spouttuples是否安全到达bolt)。对于处理输入tuple的一般情况而言, Storm提供IBasicBolt接口,这个接口可以自动进行acking。
值得推荐的是:bolts中新加载的线程如果是以异步方式进行处理。OutputCollector是多线程安全的,并且可以在任何时候被调用。
资料:
l IRichBolt:这是bolts的一般接口
l IBasicBolt:这是定义bolts进行过滤以及简单功能计算时的方便接口
l OutputCollector:使用这个类的实例可以发射tuples到它们的输出流
l 保证消息处理机制
Stream grouping
定义一个topology的其中一部分就是指定每个bolt接收哪些输入流。 stream grouping可以定义stream 怎么在bolt任务之间划分。
Storm中有7种内置的streamgrouping方式,可以通过实现CustomStreamGrouping接口的方式实现自己的stream grouping:
1、Shuffle grouping: Tuples随机的发送到bolts的tasks, 这样可以保证每个bolt都可以获得相同数目的tuples。
2、Fields grouping: 数据流通过grouping中特定fields进行划分。 例如,如果数据流通过“user-id” field进行分组,则tuples也是用相同的“user-id”划分,这样可以保证相同“user-id”的tuple可以流向相同的task,但是带有不同“user-id”的tuples可能流向不同的tasks。
3、All grouping: stream向bolt所有的tasks发送副本。使用这种方式使要当心。(?,原文没解释)
4、Global grouping: 整个流都流向bolt tasks之一。需要指出的是, 这个stream 将流向带有最小id的task
5、None grouping:这种grouping指明,你不需要关心stream是如何分组的。 当前来说, nonegrouping方式与shuffle grouping方式相同。最终是,Storm将会推动使用none grouping方式bolts在相同的线程执行,同样他也会推动这些bolts订阅的bolts或者spouts也这样做(当可能时)。
6、Direct grouping: 这是一种特殊grouping
方式。使用这种方式分组的流意味着, tuples的生产者决定了哪些消费者来接受这些tuples。Direct grouping只能用于那些声明为direct stream的streams。发射到direct stream的tuples必须采用emitDirect方式发射。bolt可以通过使用已有的TopologyContext类获得它的消费者的taskids,或者是保持对OutputCollector类(它将返回tuple发向的task ids)中emit方法输出的追踪,也可以获得taskids。
7、Local or shufflegrouping:如果目标bolt在相同worker进程上有一个或多个tasks, tuples将随机的发送到这些进程内tasks。否则, 这就像一般的shufflegrouping。
资料:
l TopologyBuilder: 使用这个类定义topologies
l InputDeclarer:TopologyBuilder无论何时调用setBolt都会返回这个对象, 或者用来声明bolt的输入流以及这些流应当怎样分组
l CoordinatedBolt:分布式RPCtopologies使用这个bolt,并且这个bolt在direct streams和direct grouping中有重要使用。(这个类的地址已经找不到了)
Reliability
Storm可以保证: 每个spout tuple都将在topology中得到完整的处理。 这是通过追踪tuples在topology中不同节点经过时形成的树状路线图获得的,通过追踪可以确定何时可以成功的完成tuples的树状路线图。每一个topology都有一个消息超时机制来辅助这个追踪。如果storm在限定时间内没有检测到一个spout tuple已经完成它的树状图,则它会抛弃这个tuple并重新发送它。
若是利用storm可靠性特征,你必须告知Storm,在tuple 树状图中,新的处理edges何时被创建;并且需要告诉Storm,何时完成一个单独tuple的处理。这些都在OutputCollector对象(即bolt用来发射tuple的对象)中完成。锁定发射目的地是在emit方法中完成,使用ack方法可以声明你已经完成一个tuple的处理。
更多细节解释可以查看消息处理保证机制。
Tasks
每个spout和bolt在cluster中都可以执行很多tasks。每个task与执行线程之一相关, stream grouping定义了如何从一系列tasks发送到另一系列的tasks。你可以使用TopologyBuilder类中setSpout和setBolt方法定义每个spout或者bolt的并行机制。
workers
Topologies 可以执行一个或多个worker 进程。 每个worker进程是一个物理上JVM(即一台机器?)并且执行topology中所有tasks的一个子集。 例如, 如果topology并行数总和是300, 同时分配了50个workers, 那么每个worker可以执行tasks(即在worker中线程数)。 Storm尽量在所有workers之间平均分配tasks。
资料:
l Config.TOPOLOGY_WORKERS: 这个配置选项可以配置topology中workers的数量。