storm各组件特点

1.

*spout—–数据源(吐数据进入拓扑)*

<1>可以一次向多个流吐数据。
此时需要OutputFieldsDeclarer中的declareStream函数来声明多个流,并在调用 SpoutOutputCollecter的emit方法指定元组(tuple)吐给哪个流(streams)。
eg:
//声明流
public void declareOutputFields(OutputFieldsDeclarer declarer) {

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

  }
//
public void open(Map<String, Object> conf, TopologyContext context, SpoutOutputCollector collector) {

    _collector = collector;

    _rand = new Random();

  }



  @Override

  public void nextTuple() {

    Utils.sleep(100);

    String[] sentences = new String[]{sentence("the cow jumped over the moon"), sentence("an apple a day keeps the doctor away"),

            sentence("four score and seven years ago"), sentence("snow white and the seven dwarfs"), sentence("i am at two with nature")};

    final String sentence = sentences[_rand.nextInt(sentences.length)];



    LOG.debug("Emitting tuple: {}", sentence);


//发送数据
    _collector.emit(new Values(sentence));

  }

<2>nextTuple——spout中的最主要函数
Storm框架会不断调用它去做元组的轮询。如果没有新的元组过来,就直接返回,否则把新元组吐到拓扑里。nextTuple必须是非阻塞的,因为Storm在同一个线程里执行Spout的函数。
<3>ack&fail
当Storm检测到一个从Spout吐出的元组在拓扑中成功处理完时调用ack,没有成功处理完时调用fail。只有可靠型的Spout会调用ack和fail函数。

2.

bolt—–流水线上的处理单元—–实现计算和逻辑

3.

topology

<1>steam grouping——定义流在bolt内的Task如何分组
在Storm中有七个内置的流分组策略,也可以通过实现CustomStreamGrouping接口来自定义一个流。
分组策略:
洗牌分组(Shuffle grouping): 随机分配元组到Bolt的某个任务上,这样保证同一个Bolt的每个任务都能够得到相同数量的元组。
字段分组(Fields grouping): 按照指定的分组字段来进行流的分组。例如,流是用字段“user-id”来分组的,那有着相同“user-id”的元组就会分到同一个任务里,但是有不同“user-id”的元组就会分到不同的任务里。这是一种非常重要的分组方式,通过这种流分组方式,我们就可以做到让Storm产出的消息在这个”user-id”级别是严格有序的,这对一些对时序敏感的应用(例如,计费系统)是非常重要的。
Partial Key grouping: 跟字段分组一样,流也是用指定的分组字段进行分组的,但是在多个下游Bolt之间是有负载均衡的,这样当输入数据有倾斜时可以更好的利用资源。这篇论文很好的解释了这是如何工作的,有哪些优势。
All grouping: 流会复制给Bolt的所有任务。小心使用这种分组方式。在拓扑中,如果希望某类元祖发送到所有的下游消费者,就可以使用这种All grouping的流分组策略。
Global grouping: 整个流会分配给Bolt的一个任务。具体一点,会分配给有最小ID的任务。
不分组(None grouping): 说明不关心流是如何分组的。目前,None grouping等价于洗牌分组。
Direct grouping:一种特殊的分组。对于这样分组的流,元组的生产者决定消费者的哪个任务会接收处理这个元组。只能在声明做直连的流(direct streams)上声明Direct groupings分组方式。只能通过使用emitDirect系列函数来吐元组给直连流。一个Bolt可以通过提供的TopologyContext来获得消费者的任务ID,也可以通过OutputCollector对象的emit函数(会返回元组被发送到的任务的ID)来跟踪消费者的任务ID。在ack的实现中,Spout有两个直连输入流,ack和ackFail,使用了这种直连分组的方式。
Local or shuffle grouping:如果目标Bolt在同一个worker进程里有一个或多个任务,元组就会通过洗牌的方式分配到这些同一个进程内的任务里。否则,就跟普通的洗牌分组一样。这种方式的好处是可以提高拓扑的处理效率,因为worker内部通信就是进程内部通信了,相比拓扑间的进程间通信要高效的多。worker进程间通信是通过使用Netty来进行网络通信的。

猜你喜欢

转载自blog.csdn.net/weixin_39419040/article/details/78689939
今日推荐