1.topology

  一个topolgy是spouts和bolts组成的图,通过stream groupings将图中的spout和bolts连接起来:如图所示:

  

  一个topology会一直运行知道你手动kill掉,Storm自动重新分配执行失败的任务,并且Storm可以保证你不会有数据丢失(如果开启了高可靠性的话)。如果一些机器意外停机它上面的所有任务会被转移到其他机器上;

  运行一个toplogy很简单,首先,把你所有的代码以及所依赖的jar打进一个jar中。然后运行类似下面的命令:

  storm jar all-my-code.jar backtype.storm.MyTopology arg1 arg2

  这个命令会运行主类:backtype.storm.MyTopology,参数是arg1,arg2。这个类的main函数定义这个topology并且把它提交给Nimbus。storm jar负责连接到Nimbus并且上传jar包;

  Topology的定义是一个Thrift结构,并且Nimbus就是一个Thrift服务,你可以提交任何语言创建的topology。上面的方法就是用JVM-based语言提交的最简单的方法。

  如下代码即定义了一个topology:

  

TopologyBuilder builder = new TopologyBuilder();

builder.setSpout("spout",new RandomSentceSpout(),5);

builder.setBolt("split",new SplitSentence(),8).shuffleGrouping("spout")

builder.setBolt("count", new WordCount(),12).fieldsGrouping("spilt",new Fields("word"));

2、Streams

  小溪流stream是storm里的关键抽象。一个消息流是一个没有边界的tuple序列,而这些tuple序列会以一种分布式的方式并行的创建和处理。再默认的情况写,tuplr的字段类型可以是:integer,long,short,byte,string,double,boolean和byte array。也可以自定义类型(只要实现相应的序列化器)。

public void declareOutputFields(OutputFieldsDeclarer declarer){
//默认ID的信息流定义
declarer.declare(new Fields("word","cout"));
//自定义ID的消息流
declare.declareStream("streamId",new Fields("word","count"));
}

  每个消息流再定义的时候会被分配给一个id,因为单向消息流使用的相当普遍,OutputFieldsDeclarer定义了一些方法让你可以定义一个stream而不用制定这个id。在这种情况下这个stream会分配个值为‘default’默认的id。

  Storm提供的最近本的处理stream的原语是spout和bolt。你可以实现spout和bolt提供的接口来处理你的业务逻辑。

3、Soupts

  消息源spout是Storm里面一个topology里面的消息生产者。一般来说消息源会从一个外部源读取数据并且向topology里面发送出消息:tuple。Spout可以是可靠地也可以是不可靠的。如果这个tuple没有被storm成功处理,可靠地消息源spouts可以重新发射一个tuple,但是不可靠的消息源spouts一旦发出一个tuple就不能重发了。

  消息源可以发射多条消息流stream。使用OutputFieldsDeclarer。declareStream来定义多个stream,然后使用SpoutOutputCollector来发射指定的stream。

/**
*定义了2个消息流
*/
public void declareOutputFields (OutputFieldsDeclarer declarer){
declarer.declareStream("streamId1",new Fields("words"));
declarer.declareStream("streamId2",new Fields("word2"));
}
/**
*根据消息流发射相应的消息
*/
public void nextTuple(){
collector.emit("streamId1",new Values("streamid1's word1"));
collector.emit("streamId2".new Values("streamid2's word2"));
}

  Spout类里面最重要的方法是nextTuple。要么发射一个新的tuple到topology里面或者简单的返回如果已经没有新的tuple。要注意的是nextTuple方法不能阻塞,因为storm在同一个线程上面调用所有消息源spout的方法。

  另外两个比较重要的spout方法是ack和fail。storm在检测到一个tuple被整个topology成功处理的时候调用ack,否则调用fail。storm只对可靠的spout调用ack和fail。

4、Bolts

  所有的消息处理逻辑被封装在bolts里面。Bolts可以做很多事情:过滤,聚合,查询数据库等等;

  Bolts可以简单地做消息流的传递。复杂的消息流处理往往需要很多步骤,从而就需要经过很多bolts。

  Bolts和spouts一样,可以发射多条消息流,使用OutputFieldsDeclarer。declareStream定义stream,使用OutputCollector.emit来选择要发射的stream。

  Bolts的主要方法是execute,他以一个tuple作为输入,使用OutputCollector来发射tuple,bolts必须要为它处理的每一个tuple调用OutputCollector的ack方法,以通知Storm这个tuple被处理完成了,从而统治这个tuple的发射这spouts.一般的流程是:bolts处理一个输入tuplr,发射0个或者多个tuple,然后调用ack通知storm自己已经处理过这个tuple了。storm提供了一个IBasicBolt会自动调用ack。

5、Stream Grouping

  定义一个 toplogy的其中一步是定义每个bolt接受什么样的流作为输入。stream grouping就是用来定义一个stream应该如果分配数据个ibolts上面的多个tasks。

  Storm里面有7种类型的stream grouping:

  --Shuffle Grouping:随机分组,随机派发stream里面的tuple,保证每个bolt接受到的tuple数目大致相同;

  --Fields Grouping:按字段分组,比如按userid来分组,具有同样的userid的tuple会被分到相同的Bolts里的一个task,而不同的userid则会被分配到不同的bolts里面的task。

  --All Grouping:广播发送,对于每一个tuple,所有的bolts都会受到。

  --Global Grouping:全局分组,这个tuple被分配到storm中的一个bolt的其中一个task。再具体一点就是分配给id值最低的那个task。

  --Non Grouping:不分组,这个分组的意思是说stream不关心到底谁会受到它的tuple。目前这种分组和Shuffle grouping是一样的效果,有一点不同的是storm会把这个bolt放到这个bolt的订阅者同一个线程里面去执行。

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

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

代码示例:

TopologyBuisder builder = new TopologyBuilder();

builder.setSpout("spout",new RandomSentenceSpout(),5);
builder.setBolt("split",new SplitSentence(),8).shuffleGrouping("spout");
builder.setBolt("count",new WordCount(),12).fieldsGrouping("spilt",new Fields("word")):

6.Reliability

  storm保证每个tuple会被topology完整的执行。Storm会追踪有每个spout tuple所含生的tuple树(一个bolt处理一个tuple之后可能会发射别的tuple从而形成树状结构),并且跟踪这颗tuple树什么时候成功处理完。每个topology都有一个消息超时的设置,如果storm在这个超市的时间内检测不到某个tuple树到底有没有执行成功,那么topology会把这个tuple标记为执行失败,并且过一会重新发射这个tuple。

  为了利用Strom的可靠性特性,在你发出一个新的tuple以及你完成处理一个tuple的时候你必须要通知storm。这一切是由OutputCollector来完成的。通过emit方法来通知一个新的tuple产生了,通过ack方法通知一个tuple处理完成了。

7、Tasks

  每一个spout和bolt会被当做很多task在整个集群里执行。每一个executor对应到一个线程,在这个线程上运行多个task,而stream grouping则是定义怎么从一堆task发射tuple到另外一堆task。你可以调用TopologyBuilder类里的setSpout和setBolt来设置并调度(也就是有多少个task)。

代码示例如下:

ToplogyBuilder builder = new TopologyBuilder();

builder.setSpout("spout",new RandomSentenceSpout(),5).setNumTasks(10);
builder.setBolt("spilt",new SplitSentence(),8).shuffleGrouping("spout").setNumTasks(8);
builder.setBolt("count",new WoedCount(),12).fieldsGrouping("split",new Fields("woed")).setNumTasks(24);

表示“spout”的线程数为5,任务数为10,即一个线程运行两个任务;

“split”则为一个线程运行一个任务,和默认的一致。

8.Workers

  一个topology可能会在一个或者多个worker(工作进程)里面执行,每个worker是一个屋里JVM并执行整个topology的一部分。比如,对于并行度是300的topology来说,如果我们使用50个工作进程来执行,那么每个工作进程会开启6个线程,默认默认每个线程处理一个tasks。Storm会尽量均匀的工作分配给所有的worker。每个supervisor上运行着若干个worker进程(根据配置文件supervisor.slots.ports进行配置)。

9.Configuration

  Storm里面有一堆参数可以配置来调整Nimbus,Supervisor以及正在运行的topology的行为,一些配置是系统级别的,一些配置是topology级别的。default。yaml里面有所有的默认配置。你可以通过定义一个storm.yaml在你的classpath里面来覆盖这些默认的配置并且你也可以在代码里面设置一些topology相关的配置信息(使用StromSubmitter)。

storm中的一些概念的更多相关文章

  1. storm中的基本概念

    Storm是一个流计算框架,处理的数据是实时消息队列中的,所以需要我们写好一个topology逻辑放在那,接收进来的数据来处理,所以是通过移动数据平均分配到机器资源来获得高效率. Storm的优点是全 ...

  2. 2、Storm中的一些概念理解

    1.Tuple,Value,Field Tuple官方解释: "A tuple is a named of values where each value can be any type.& ...

  3. storm中几个概念的大小关系

    从图可以看出来:topology>supervisor>worker>excutor>task; 也就是说一个topology可以运行在多个supervisor上,一个supe ...

  4. Storm中遇到的日志多次重写问题(一)

    业务描述: 统计从kafka spout中读取的数据条数,以及写入redis的数据的条数,写入hdfs的数据条数,写入kafaka的数据条数.并且每过5秒将数据按照json文件的形式写入日志.其中保存 ...

  5. Storm入门1-基本概念

    [本篇文章主要是介绍Storm的特点.核心概念.以及Storm的生态现状:从总体上对storm有个基本的认识] Storm是Apache下的一个免费的.开源的.分布式流式计算框架,官方网址:https ...

  6. Storm中并发程度的理解

    Storm中涉及到了很多组件,例如nimbus,supervisor等等,在参考了这两篇文章之后,对这个有了更好的理解. Understanding the parallelism of a Stor ...

  7. storm中worker、executor、task之间的关系

    这里做一些补充: worker是一个进程,由supervisor启动,并只负责处理一个topology,所以不会同时处理多个topology. executor是一个线程,由worker启动,是运行t ...

  8. WebLogic 中的基本概念

    完全引用自: WebLogic 中的基本概念 WebLogic 中的基本概念 上周参加了单位组织的WebLogic培训,为了便于自己记忆,培训后,整理梳理了一些WebLogic的资料,会陆续的发出来, ...

  9. Storm中Spout使用注意事项小结

    Storm中Spout用于读取并向计算拓扑中发送数据源,最近在调试一个topology时遇到了系统qps低,处理速度达不到要求的问题,经过排查后发现是由于对Spout的使用模式不当导致的多线程同步等待 ...

随机推荐

  1. c/c++ include 头文件的方式

    在编写c/c++代码时,#include 头文件有两种方式:一个是#include “文件名”,一个是#include <文件名>.区别在于: 前者在程序编译时系统首先在源程序所在的目录( ...

  2. 在Linux系统上安装Oracle数据库

    前期准备:我用的是虚拟机上的CentOS 64位系统.所以需要设置网卡,时间,EPEL源,安装一些必备的软件. 1.1在虚拟机上安装好Linux系统后选择虚拟机设置—>网络适配器—>网络连 ...

  3. (转)es6中object.create()和object.assign()

    今天学习javascript面向对象,在学习Obejct方法时了解到create方法,偶像想起之前使用的assign方法,顺带查找一番,感觉这篇博客讲解详细,遂转载. 先简单提一下装饰器函数,许多面向 ...

  4. 开始Python学习

    主要结合ArcGIS进行空间数据处理 Python最讨厌的就是版本问题了 ArcGIS 10.5安装的时候已经安装了python2.7.13,但后来又安装了python3.6.1. 环境变量的设置: ...

  5. intellij idea解除svn关联

    有时候项目需要解除svn关联,百度谷歌几篇,以下方式是最简单快捷的. 从.idea文件夹下手,找到了cvs.xml,其内容如下: <?xml version="1.0" en ...

  6. PHP编译安装报错:configure: error: mcrypt.h not found. Please reinstall libmcrypt

    我是在CentOS6.5安装php5.5.28这个版本,PHP编译代码如下: ./configure --prefix=/usr/local/php --with-config-file-path=/ ...

  7. 安装系统后IP配置问题

    1.配置静态IP 在/etc/sysconfig/network-script/ifcfg-eth0 文件,网卡管理文件.修改为静态IP.IPADDR.网关.掩码等 同一台机器上的网卡不能配置在同一网 ...

  8. Visual C++ 6.0对任意三个数字进行排序

    # include <stdio.h> int main (void) { int a, b, c; int t; printf("请输入三个整数,中间以空格隔开:") ...

  9. tableview前端基础设计(初级版)

    tableView前端基础设计 实现的最终效果 操作目的:熟悉纯代码编辑TableView和常用的相关控件SearchBar.NavigationBar.TabBar等,以及布局和基本功能的实现. 一 ...

  10. 安卓APP性能测试的一些方面

    1. 启动速度 2. 点击/滑动等事件响应速度 3. 下载速度 4. 界面流畅程度,比较帧率 5. 耗电量测试 6. 流量测试 7. 内存泄漏 8. CPU 9. Monkey adb -s FJH5 ...