概念:

Workers (JVMs): 在一个节点上可以运行一个或多个独立的JVM 进程。一个Topology可以包含一个或多个worker(并行的跑在不同的machine上), 所以worker process就是执行一个topology的子集, 并且worker只能对应于一个topology

Executors (threads): 在一个worker JVM进程中运行着多个Java线程。一个executor线程可以执行一个或多个tasks。但一般默认每个executor只执行一个task。一个worker可以包含一个或多个executor, 每个component (spout或bolt)至少对应于一个executor, 所以可以说executor执行一个compenent的子集, 同时一个executor只能对应于一个component。

Tasks(bolt/spout instances):Task就是具体的处理逻辑对象,每一个Spout和Bolt会被当作很多task在整个集群里面执行。每一个task对应到一个线程,而stream grouping则是定义怎么从一堆task发射tuple到另外一堆task。你可以调用TopologyBuilder.setSpout和TopBuilder.setBolt来设置并行度 — 也就是有多少个task。

配置并行度

对于并发度的配置, 在storm里面可以在多个地方进行配置, 优先级为:defaults.yaml < storm.yaml < topology-specific configuration < internal component-specific configuration < external component-specific configuration

worker processes的数目, 可以通过配置文件和代码中配置, worker就是执行进程, 所以考虑并发的效果, 数目至少应该大亍machines的数目

executor的数目, component的并发线程数,只能在代码中配置(通过setBolt和setSpout的参数), 例如, setBolt("green-bolt", new GreenBolt(), 2)

tasks的数目, 可以不配置, 默认和executor1:1, 也可以通过setNumTasks()配置

Topology的worker数通过config设置,即执行该topology的worker(java)进程数。它可以通过 storm rebalance 命令任意调整。

1
2
3
4
5
6
Config conf = new Config();
conf.setNumWorkers(2); // use two worker processes
topologyBuilder.setSpout("blue-spout", new BlueSpout(), 2); // set parallelism hint to 2
topologyBuilder.setBolt("green-bolt", new GreenBolt(), 2).setNumTasks(4).shuffleGrouping("blue-spout"); //set tasks number to 4
topologyBuilder.setBolt("yellow-bolt", new YellowBolt(), 6).shuffleGrouping("green-bolt");
StormSubmitter.submitTopology("mytopology", conf, topologyBuilder.createTopology());

动态的改变并行度

Storm支持在不 restart topology 的情况下, 动态的改变(增减) worker processes 的数目和 executors 的数目, 称为rebalancing. 通过Storm web UI,或者通过storm rebalance命令实现:

1
storm rebalance mytopology -n 5 -e blue-spout=3 -e yellow-bolt=10

流分组策略----Stream Grouping

Stream Grouping,告诉topology如何在两个组件之间发送tuple 
定义一个topology的其中一步是定义每个bolt接收什么样的流作为输入。stream grouping就是用来定义一个stream应该如果分配数据给bolts上面的多个tasks

Storm里面有7种类型的stream grouping,你也可以通过实现CustomStreamGrouping接口来实现自定义流分组 
1. Shuffle Grouping 
随机分组,随机派发stream里面的tuple,保证每个bolt task接收到的tuple数目大致相同。

2. Fields Grouping 
按字段分组,比如,按"user-id"这个字段来分组,那么具有同样"user-id"的 tuple 会被分到相同的Bolt里的一个task, 而不同的"user-id"则可能会被分配到不同的task。

3. All Grouping 
广播发送,对亍每一个tuple,所有的bolts都会收到

4. Global Grouping 
全局分组,整个stream被分配到storm中的一个bolt的其中一个task。再具体一点就是分配给id值最低的那个task。

5. None Grouping 
不分组,这个分组的意思是说stream不关心到底怎样分组。目前这种分组和Shuffle grouping是一样的效果, 有一点不同的是storm会把使用none grouping的这个bolt放到这个bolt的订阅者同一个线程里面去执行(如果可能的话)。

6. Direct Grouping 
指向型分组, 这是一种比较特别的分组方法,用这种分组意味着消息(tuple)的发送者指定由消息接收者的哪个task处理这个消息。只有被声明为 Direct Stream 的消息流可以声明这种分组方法。而且这种消息tuple必须使用 emitDirect 方法来发射。消息处理者可以通过 TopologyContext 来获取处理它的消息的task的id (OutputCollector.emit方法也会返回task的id)

7. Local or shuffle grouping 
本地或随机分组。如果目标bolt有一个或者多个task与源bolt的task在同一个工作进程中,tuple将会被随机发送给这些同进程中的tasks。否则,和普通的Shuffle Grouping行为一致。 
----------------------------------------------------------------------------------------

在这里,将会提到storm的七种grouping策略,并且编码逐一实现。

首先,需要一个集群(希望尽量模仿真实环境,故就不用本地模式了)。详细的安装方法大家可以查看本人的另外一篇博文:storm集群和zookeeper集群的部署过程。

OK。现在有三个节点。一个作为nimbus,两个作为supervisor。到这里先介绍一下storm逻辑上有两个component,一个是Spout,另一个是Bolt。stream由Spout发出,在不同的Bolt之间进行处理,在其中传递的是storm的基本处理单位:Tuple。由Spout发出一个一个Tuple,然后Bolt接收Tuple进行各种各样的处理。这一整个过程构成一个DAG。在storm里面叫做Topology。当使用远程模式向集群提交一个Topology之后,如果不kill掉的话,将会一直运行到。。。我也不知道尽头。。貌似没有尽头。

好了,来看一个简单的Topology。将使用这个Topology来实现那几种Grouping策略。

上图中spout的处理逻辑是将一句话发出给下一个Bolt,然后下一个Bolt做句子的单词分割,下一个做计数,最后的Bolt做汇总显示。这里可以有多个Bolt或者Spout进行并行处理。这是关于并行度的设置。

好了,所谓的grouping策略就是在Spout与Bolt、Bolt与Bolt之间传递Tuple的方式。总共有七种方式:

1)shuffleGrouping(随机分组)

2)fieldsGrouping(按照字段分组,在这里即是同一个单词只能发送给一个Bolt)

3)allGrouping(广播发送,即每一个Tuple,每一个Bolt都会收到)

4)globalGrouping(全局分组,将Tuple分配到task id值最低的task里面)

5)noneGrouping(随机分派)

6)directGrouping(直接分组,指定Tuple与Bolt的对应发送关系)

7)Local or shuffle Grouping

8)customGrouping (自定义的Grouping)

OK,下面逐个来试试!

首先是使用shuffleGrouping策略。

启动后所得的结果。

可以看到如storm这个单词被随机分配到了两个counter里面,分别是h4和h3两个节点里面。可再做一次提交,又会看到不一样的结果。将与下面的fieldGrouping形成对比。

然后换成fieldsGrouping。

启动后的结果如图。图中wordcount2和wordcount3就是我两次提交的topology的名字。

下面是两次提交的结果。可以看出,使用fieldsGrouping策略,被分配到每个wordcounterbolt的单词没有变化。

下面是第二次提交的结果。

再换成noneGrouping策略。

提交集群运行。

运行结果如图。noneGrouping和shuffleGrouping是基本一样的。都是随机的。

替换成allGrouping策略。

提交集群运行。

运行结果如图。可以看到。两个bolt所接收到的单词是一样的,都是全部的单词。

最后,替换成globalGrouping策略。

提交集群运行。

从上图可以看到,主要分配到了h3这个节点。从下面的结果得以验证。

好了,就先做到这里吧!

----------------------------------------------------------------------------------------

消息的可靠处理机制

在storm中,可靠的信息处理机制是从spout开始的。一个提供了可靠的处理机制的spout需要记录他发射出去的tuple,当下游bolt处理tuple或者子tuple失败时spout能够重新发射。

Storm通过调用Spout的nextTuple()发送一个tuple。为实现可靠的消息处理,首先要给每个发出的tuple带上唯一的ID,并且将ID作为参数传递给SoputOutputCollector的emit()方法:collector.emit(new Values("value1","value2"), msgId); 给tuple指定ID告诉Storm系统,无论处理成功还是失败,spout都要接收tuple树上所有节点返回的通知。如果处理成功,spout的ack()方法将会对编号是msgId的消息应答确认;如果处理失败或者超时,会调用fail()方法。

bolt要实现可靠的信息处理机制包含两个步骤:1.当发射衍生的tuple时,需要锚定读入的tuple;2.当处理消息成功或失败时分别确认应答或者报错。

锚定一个tuple的意思是,建立读入tuple和衍生出的tuple之间的对应关系,这样下游的bolt就可以通过应答确认、报错或超时来加入到tuple树结构中。可以通过调用OutputCollector的emit()的一个重载函数锚定一个或一组tuple:collector.emit(tuple, new Values(word))

非锚定(collector.emit(new Values(word));)的tuple不会对数据流的可靠性起作用。如果一个非锚定的tuple在下游处理失败,原始的根tuple不会重新发送。 
  
    超时时间可以通过任务级参数Config.TOPOLOGY_MESSAGE_TIMEOUT_SECS进行配置,默认超时值为30秒。

Storm 系统中有一组叫做"acker"的特殊的任务,它们负责跟踪DAG(有向无环图)中的每个消息。acker任务保存了spout消息id到一对值的映射。第一个值就是spout的任务id,通过这个id,acker就知道消息处理完成时该通知哪个spout任务。第二个值是一个64bit的数字,我们称之为"ack val", 它是树中所有消息的随机id的异或计算结果。ack val表示了整棵树的的状态,无论这棵树多大,只需要这个固定大小的数字就可以跟踪整棵树。当消息被创建和被应答的时候都会有相同的消息id发送过来做异或。

每当acker发现一棵树的ack val值为0的时候,它就知道这棵树已经被完全处理了。因为消息的随机ID是一个64bit的值,因此ack val在树处理完之前被置为0的概率非常小。假设你每秒钟发送一万个消息,从概率上说,至少需要50,000,000年才会有机会发生一次错误。即使如此,也只有在这个消息确实处理失败的情况下才会有数据的丢失!

有三种方法可以去掉消息的可靠性: 
1、将参数Config.TOPOLOGY_ACKERS设置为0,通过此方法,当Spout发送一个消息的时候,它的ack方法将立刻被调用; 
2、Spout发送一个消息时,不指定此消息的messageID。当需要关闭特定消息可靠性的时候,可以使用此方法; 
3、最后,如果你不在意某个消息派生出来的子孙消息的可靠性,则此消息派生出来的子消息在发送时不要做锚定,即在emit方法中不指定输入消息。因为这些子孙消息没有被锚定在任何tuple tree中,因此他们的失败不会引起任何spout重新发送消息。 

Storm-6 Storm的并行度、Grouping策略以及消息可靠处理机制简介的更多相关文章

  1. Storm的并行度、Grouping策略以及消息可靠处理机制简介

    转自:https://my.oschina.net/zc741520/blog/409949 概念: Workers (JVMs): 在一个节点上可以运行一个或多个独立的JVM 进程.一个Topolo ...

  2. Storm消息可靠处理机制

    在很多应用场景中,分布式系统的可靠性保障尤其重要.比如电商平台中,客户的购买请求需要可靠处理,不能因为节点故障等原因丢失请求:比如告警系统中,产生的核心告警必须及时完整的知会监控人员,不能因为网络故障 ...

  3. Storm编程入门API系列之Storm的Topology的stream grouping

    概念,见博客 Storm概念学习系列之stream grouping(流分组) Storm的stream grouping的Shuffle Grouping 它是随机分组,随机派发stream里面的t ...

  4. 【Storm】storm安装、配置、使用以及Storm单词计数程序的实例分析

    前言:阅读笔记 storm和hadoop集群非常像.hadoop执行mr.storm执行topologies. mr和topologies最关键的不同点是:mr执行终于会结束,而topologies永 ...

  5. storm之8:并行度

    (一)storm拓扑的并行度可以从以下4个维度进行设置:1.node(服务器):指一个storm集群中的supervisor服务器数量.2.worker(jvm进程):指整个拓扑中worker进程的总 ...

  6. Storm 第三章 Storm编程案例及Stream Grouping详解

    1 功能说明 设计一个topology,来实现对文档里面的单词出现的频率进行统计.整个topology分为三个部分: SentenceSpout:数据源,在已知的英文句子中,随机发送一条句子出去. S ...

  7. Storm概念学习系列之并行度与如何提高storm的并行度

    不多说,直接上干货! 对于storm来说,并行度的概念非常重要!大家一定要好好理解和消化. storm的并行度,可以简单的理解为多线程. 如何提高storm的并行度? storm程序主要由spout和 ...

  8. storm学习-storm入门

    超好资料: 英文:https://github.com/xetorthio/getting-started-with-storm/blob/master/ch03Topologies.asc 中文:h ...

  9. Storm入门-Storm与Spark对比

    作为一名程序员通病就是不安分,对业界的技术总要折腾一番,哪怕在最终实际工作中应用到的就那么一点.最近自己准备入门Storm学习,关于流式大数据框架目前比较流行的有Spark和Storm等,在入门之前, ...

随机推荐

  1. C# foreach循环绑定key数组和value 数组(备用)

    <div class="ContextualTab inner_warp clearfix" data-max="2" data-blur=false d ...

  2. VBScript 函数

    Date/Time 函数 Conversion 函数 Format 函数 Math 函数 Array 函数 String 函数 其他函数 Date/Time 函数 函数 描述 CDate 把一个有效的 ...

  3. Oracle 9 - redo和undo

    1.redo redo 有在线redo日志和归档redo日志, 从Oracle 10g开始还新增加了flashback技术. 每个Oracle数据库至少有2个在线重做日志组,循环写. 只有INSERT ...

  4. 使用预处理PreparedStatement执行Sql语句

    /** * 使用预处理的方式执行Sql * @param sql Sql语句 * @param obj 变量值数组 * @return 查询结果 * @throws SQLException */ p ...

  5. lintcode:Fibonacci 斐波纳契数列

    题目: 斐波纳契数列 查找斐波纳契数列中第 N 个数. 所谓的斐波纳契数列是指: 前2个数是 0 和 1 . 第 i 个数是第 i-1 个数和第i-2 个数的和. 斐波纳契数列的前10个数字是: 0, ...

  6. 大陆 Google play 开发者注册(2016)

    1:准备一个VPN, 如:  https://vpnso.com   收费的,使用一两年了,还不错,很稳定2:准备一张普通的银行卡或者信用卡就可以了,能正常绑定支付宝就行3:在全球付上面申请一个 虚拟 ...

  7. mysql级联删除更新

    首先,目前在产品环境可用的MySQL版本(指4.0.x和4.1.x)中,只有InnoDB引擎才允许使用外键,所以,我们的数据表必须使用InnoDB引擎. 下面,我们先创建以下测试用数据库表: CREA ...

  8. C++Builder和VC的比较

    C++Builder和VC的比较 其实很久以前我就想写这篇文章,其原因一方面是因为笔者深深感觉到C++ Builder的确是一个先进与强大的程式开发工具,但更最重要的一点是,我深信C++ Builde ...

  9. JDBC批处理---(java 对数据库的回滚) .

    1先看一下程序: package com.redking.jdbc.demo;    import java.sql.Connection;    import java.sql.DriverMana ...

  10. Android之NDK编程(JNI)

    转自:http://www.cnblogs.com/xw022/archive/2011/08/18/2144621.html NDK编程入门--C回调JAVA方法   一.主要流程 1.  新建一个 ...