概述

上一篇【storm初识】 博文连接:

     本文将对storm的概念进行解释和进一步阐述,将要讲解的概念有:

Topologies (拓扑)

Streams (数据流)

Spouts (发射器,瀑布)

Bolts ( 闪电 ,处理者)

Stream groupings (流群组)

Reliability (可靠性)

Tasks (任务)

Workers (角色,工作者)

名词解释

Topologies (拓扑)

     topologies是实时处理计算的程序逻辑的程序包,一个topologies类似于一个 MapReduce  任务,MapReduce  任务是最终完成,而一个拓扑可以永远运行(只到你杀死它为止)。一个topologies是Spouts和Bolts 在storm集群中连接关系结构图。

      后续还会有详细的在生产以及本地部署、测试、提交Topologies学习和介绍。请大家多多关注!!!

Streams (数据流)

    Streams是storm中一个核心的概念,它是在分布式并行处理和创建的无限序列元组,Streams通过给流元组中字段命名来定义,默认情况下,元组可以包含整型,长整型,短整型,字节,字符串,布尔型,双精度浮点型,单精度浮点型,字节数组,也可以自定义序列化类型。

     声明任何一个stream需要给定一个ID(非必须),单一stream,一个Spouts对应一个Bolts也是很常见。“OutputFieldsDeclarer” 接口为声明没有指定id的stream提供个简便的方法,这种情况下,stream会有一个名称为“ "default"  的默认id。流是有元组组成。

     后续还会有详细讲解 Tuple(元组),OutputFieldsDeclarer,元组中动态类型以及自定义序列化,请多多关注!!!

Spouts (发射器,瀑布)

    Spouts是一个拓扑中stream(数据流)的源头,通常情况下,Spouts从其他应用源(消息等数据载体)读取 tuples(元组) ,发送到拓扑中,spouts可以是可靠或不可靠两者之一,当一个 tuples(元组)被storm处理失败时, 可靠的Spouts将自动重新发送,不可靠的Spouts会丢弃。

    Spouts可以发送不止一个数据流,当使用SpoutOutputCollector的emit方法发送时,可以通过OutputFieldsDeclarer的declareStream方法声明多个Stream(数据流)和指定数据流进行发送。

     Spouts  中有个重要的方法--nextTuple。nextTuple方法可以发送一个新的Tuple(元组)到拓扑,如果没有新的元组需要发送,则会直接返回。nextTuple方法不会影响任何Spouts 的实现,所以storm可以在相同的线程内调用所有spout方法。

    Spouts  中还有另外两个重要的方法--ack 和 fail,storm发现一个spout发送Tuple(元组)完全成功或者失败是就会调用,这两个方法只会被可靠Spouts调用。

    后续还会有详细讲解  如何声明Spouts以及 Spouts   如何有效的处理消息,请多多关注!!!

 Bolts ( 闪电 ,处理者)

    拓扑中的所有处理工作都在bolts中执行,bolts可以做过滤,功能,计算,合并,数据库交互等等处理元组的操作。

    bolts可以做一些简单数据流传输,如果做复杂的数据流传输,需要分成多步使用多个bolt。比如,转移一个流为统计图至少需要两步:一个bolt为没一个统计图循环汇总统计数据,在生成某个统计图前需要一个或者多个bolt进行转换(多个比一个的伸缩性更强)。

     bolts 可以发送不止一个数据流,当使用OutputCollector的emit方法发送时,可以通过OutputFieldsDeclarer的declareStream方法声明多个Stream(数据流)和指定数据流进行发送。

      当声明一个bolt的输入流时,就需要订阅特定数据流的另一个组件。如果需要订阅另一个组件的所有数据流,就必须一个一个订阅。InputDeclarer有个简便的语法,可以在默认stream ID上订阅这个数据流。比如,declarer.shuffleGrouping("1") 和 declarer.shuffleGrouping("1", DEFAULT_STREAM_ID) 语法一样,均是订阅组件“1”上的默认stream id。

    bolts  还有一个重要的execute方法,它可以将处理好新元组发送给OutputCollector。在execute方法中,bolts 应当为每个元组调用OutputCollector的ack方法,以便storms确保每个元组都能正确的执行完成。最常见的场景是,基于一个元组发送0个或者多个元组,然后接收新的输入元组,bolts提供了一个IBasicBolt  接口自动接收。

    bolts可以很好的启用新线程进行异步处理,OutputCollector在任何时候都是线程安全的。

后续还会有详细讲解  通用接口--IRichBolt,基本接口-- IBasicBolt ,元组发射类--OutputCollector以及数据流的流转。

Stream groupings (流群组)

     一个拓扑中典型的一步就是为每个bolt指明接受哪种流作为输入。 stream grouping(流群组)定义了流在bolt 任务中如何被划分。

     Storm  中有8种内置流群组,也可以通过实现CustomStreamGrouping接口自定义一个流群组。

  1. 随机分组:元组随机的分布到各个bolt任务中,保证每个bolt处理同等数量的元组。
  2. 字段分组:根据指定字段对数据流切割分组,比如,在数据流中根据“user-id”字段分组,具有相同“user-id”字段的元组会被分到同一个任务中,不同于“user-id”字段的元组会被分到其他任务中。
  3. 侧重分组:和字段分组分组类似,根据指定字段对数据流分组,不同的是,它对下游的bolt做了负载均衡,当传入的数据倾斜时(不均衡),它可以更好的利用资源,这个文档很好的解释了它是如何更好的工作的。如有需要另起一篇关于它的详细工作原理的,可以通过评论提出。
  4. 全分组:数据流将分配到所有bolt的任务中,这个分组慎用。
  5. 全局分组:所有的流被分配到bolt其中一个任务,特别之处,它会分配到ID最小的bolt。
  6. 无分组:这种分组就是不用关心数据流是如何分组的,一般来说,无分组相当于随机分组,不过, Storm  将会在同一个线程中推送无分组的bolt给订阅了的bolt或者spout。
  7. 直接分组:这是一种特殊的分组,采用这种方式意味着,元组生产者直接决定了哪个元组消费者直接接收。该分组只能被定义为直接流的所使用,元组发送只能使用emitDirect方法,bolt可以通过提供的TopologyContext或者OutputCollector的emit方法的输出流(元组发送完毕后返回任务id)得到任务id.
  8. 本地 或 随机分组:如果目标bolt在同一个工作进程内有一个或多个任务时,元组会打乱工作进程内的任务,这机制就像一个正常的随机分组似的。

后面会有详细讲解,使用TopologyBuilder这个类构建一个拓扑,

   Reliability (可靠性)

     storm保证了每个spout发送的元组都会被成功执行,它会跟踪从每个spout发送元组触发的消息树,当每个元组被完全处理完毕才算完成,每个拓扑均有一个消息超时,如果在这个时间内,这个拓扑有一个spout元组未被处理完毕,随后storm都会重新发送这个元组。

       利用storm高可用性能,当一个元组有新的元素加入和成功处理了一个有效元组时告诉storm,bolt中调用emit方法发送消息后,通过OutputCollector对象的ack方法确保消息处理完成。

后续博文会详细的解释 storm可靠性工作原理。

Tasks (任务)

     每个spout或者bolt 都在集群任务中执行,每个任务对应着一个线程,storm集群控制如何发送一个任务组到另外一个任务组,通过TopologyBuilder的setSpout 和setBolt方法设置Spout 和Bolt的并行性。

Workers (角色,工作者)

     拓扑在一个或多个工作进程之间执行。每个工作进程是一个物理JVM,用于执行拓扑中任务的一部分,比如,有300个并行拓扑并且分配了50个工作进程,每个工作进程将会执行6个任务,storm会尽量均匀的分配到工作进程中。可以通过Config.TOPOLOGY_WORKERS 这个配置设置工作进程数执行拓扑。