storm中的一些概念
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中的一些概念的更多相关文章
- storm中的基本概念
Storm是一个流计算框架,处理的数据是实时消息队列中的,所以需要我们写好一个topology逻辑放在那,接收进来的数据来处理,所以是通过移动数据平均分配到机器资源来获得高效率. Storm的优点是全 ...
- 2、Storm中的一些概念理解
1.Tuple,Value,Field Tuple官方解释: "A tuple is a named of values where each value can be any type.& ...
- storm中几个概念的大小关系
从图可以看出来:topology>supervisor>worker>excutor>task; 也就是说一个topology可以运行在多个supervisor上,一个supe ...
- Storm中遇到的日志多次重写问题(一)
业务描述: 统计从kafka spout中读取的数据条数,以及写入redis的数据的条数,写入hdfs的数据条数,写入kafaka的数据条数.并且每过5秒将数据按照json文件的形式写入日志.其中保存 ...
- Storm入门1-基本概念
[本篇文章主要是介绍Storm的特点.核心概念.以及Storm的生态现状:从总体上对storm有个基本的认识] Storm是Apache下的一个免费的.开源的.分布式流式计算框架,官方网址:https ...
- Storm中并发程度的理解
Storm中涉及到了很多组件,例如nimbus,supervisor等等,在参考了这两篇文章之后,对这个有了更好的理解. Understanding the parallelism of a Stor ...
- storm中worker、executor、task之间的关系
这里做一些补充: worker是一个进程,由supervisor启动,并只负责处理一个topology,所以不会同时处理多个topology. executor是一个线程,由worker启动,是运行t ...
- WebLogic 中的基本概念
完全引用自: WebLogic 中的基本概念 WebLogic 中的基本概念 上周参加了单位组织的WebLogic培训,为了便于自己记忆,培训后,整理梳理了一些WebLogic的资料,会陆续的发出来, ...
- Storm中Spout使用注意事项小结
Storm中Spout用于读取并向计算拓扑中发送数据源,最近在调试一个topology时遇到了系统qps低,处理速度达不到要求的问题,经过排查后发现是由于对Spout的使用模式不当导致的多线程同步等待 ...
随机推荐
- Where do I belong (freeCodeCamp)
先给数组排序,然后找到指定的值在数组的位置,最后返回位置对应的索引. 举例:where([1,2,3,4], 1.5) 应该返回 1.因为1.5插入到数组[1,2,3,4]后变成[1,1.5,2,3, ...
- Socket通信方面
服务端 Console.WriteLine("Starting "); Socket listener = new Socket(AddressFamily.InterNetwor ...
- 《xxx系统》质量属性战术
<xxx系统>质量属性战术 可用性:重新引入 用户每填写一份表单,表单查看中即时更新所有信息. 易用性:系统主动 对于下拉框的选项较多时,用户可先进行部分输入,系统进行实时检索显示与用户输 ...
- alsa音频播放过程中的基本概念
以下为 ALSA-Project/FramesPeriods[1] 学习笔记 1, sample_rate: 即每秒进行多少次采样,常见的比如 8000.16000.44100和48000等 2, s ...
- SpringBoot1-创建SpringBoot项目
Spring Boot这两年的发展迅速,很多公司都在用,社区也越来越活越.本人也是基于此框架开发了几个项目,特和各位广大同行分享一下自己的心得体会. Spring Boot基于约束大于配置,开箱即用, ...
- tornado--输入和输出
tornado--输入和输出 tornado的self.write只接受byte,Unicode,dict三种格式的对象. self.write会存在一个缓冲区,当不强制断开缓冲的时候,它会把当前函数 ...
- poj 1113 凸包
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> ...
- HTML复习 2019-2-11
HTML复习 2019-2-11 <!doctype html> <html> <!-- 常见问题答疑 Question 1:HTML标签可以大写吗? 大小写都可以,比如 ...
- hibernate的lazy初始化结果
package com.ehcache; import java.io.Serializable; public class User implements Serializable{ private ...
- admin-6
Admin06 基本权限访问方式(权限) 读取:允许查看内容-read r 写入:允许修改内容-write w 可执行:允许运行和切换-execute x 对与文本文件: r:cat head tai ...