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. js图片库

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  2. String、StringBuilder、StringBuffer的区别

    这三个类之间的区别主要是在两个方面,即运行速度和线程安全这两方面. 首先说运行速度,或者说是执行速度,在这方面运行速度快慢为:StringBuilder > StringBuffer > ...

  3. error: 40 - 无法打开到 SQL Server 的连接

    服务器环境: 系统:windows2008 数据库:SQLSERVER2012 在与SQLServer建立连接时出现与网络相关的或特定与实例的错误.未找到或无法访问服务器.请验证实例名称是否正确并且S ...

  4. Python中使用多进程来实现并行处理的方法小结

    进程和线程是计算机软件领域里很重要的概念,进程和线程有区别,也有着密切的联系,先来辨析一下这两个概念: 1.定义 进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动,进程是系统进行资源分配和 ...

  5. SQL函数语句

    MyBatis实现模糊查询 1.${-}代替#{-} 2.把'%#{name}%'改为"%"#{name}"%" 3.使用sql中的字符串拼接函数 4.使用标签 ...

  6. mac系统访问windows共享文件夹

    1. 打开finder 2. 找到前往 - 连接服务器 3. 打开后,输入smb://ip地址  点击连接 4. 选择共享文件夹 5. 点击好,之后就可以了,如下图

  7. 用递归方法求n阶勒让德多项式的值

    /* Date: 07/03/19 15:40 Description: 用递归法求n阶勒让德多项式的值      { 1  n=0    Pn(x)= { x  n=1      { ((2n-1) ...

  8. Go学习之初出茅庐

    在一个月黑风高的夜晚,机缘巧合与Go语言一面之缘,被她的简洁.灵活.高效所吸引,让我有深入学习的冲动,现在开始我的成长之路吧.

  9. web过滤器

    Filter也称之为过滤器,它是Servlet技术中比较激动人心的技术,WEB开发人员通过Filter技术,对web服务器管理的所有web资源:例如Jsp, Servlet, 静态图片文件或静态 ht ...

  10. hql和sql的一些区别

    日期格式化查询的区别: selectSql.append(" AND DATE_FORMAT(o.createDate,\'%Y-%m-%d\') = :createDate"); ...