一、核心组件
1、Nimbus:Storm的Master,负责资源分配和任务调度。一个Storm集群只有一个Nimbus。
2、Supervisor:Storm的Slave,负责接收Nimbus分配的任务,管理所有Worker,一个Supervisor节点中包含多个Worker进程。
3、Worker:工作进程,每个工作进程中有多个Task。
4、Task:任务,在 Storm集群中每个Spout和Bolt 都由若干个task来执行。每个task都与一个执行线程相对应。
5、Topology:实时计算逻辑的封装,作用与MapReduce的Job很相似,区别在于 MapReduce的Job在得到结果之后总会结束,而拓扑会一直在集群中运行,直到你手动去终止它。
拓扑还可以理解成由一系列通过数据流(Stream Grouping)相互关联的 Spout 和 Bolt 组成的的拓扑结构。
6、Stream:指在分布式环境中并行创建、处理的一组元组(tuple)的无界序列。数据流可以由一种能够表述数据流中元组的域(fields)的模式来定义。
7、Spout:拓扑中数据流的来源。一般Spout会从一个外部的数据源读取元组然后将他们发送到拓扑中。
根据需求的不同,Spout既可以定义为可靠的数据源,也可以定义为不可靠的数据源。一个可靠的Spout能够在它发送的元组处理失败时重新发送该元组,以确保所有的元组都能得到正确的处理;相对应的,不可靠的Spout就不会在元组发送之后对元组进行任何其他的处理。一个 Spout可以发送多个数据流。
8、Bolt:完成拓扑中数据处理的组件。通过数据过滤(filtering)、函数处理(functions)、聚合(aggregations)、联结(joins)、数据库交互等功能,Bolt 几乎能够完成任何一种数据处理需求。一个 Bolt 可以实现简单的数据流转换,而更复杂的数据流变换通常需要使用多个 Bolt 并通过多个步骤完成。
二、编程
1、编写Spout
一些需要实现或覆写的重要方法
(1)open:在Spout组件初始化时被调用
(2)nextTurple:Spout的核心方法,通过collector.emit方法发射输出信息
(3)declareOutputFields:声明数据格式
@Override
public void declareOutputFields(OutputFieldsDeclarer declarer) {
declarer.declare(new Fields(field)); // 声明字段标识
}
(4)ack:tuple处理成功时调用
(5)fail:tuple处理失败时调用
(6)close:表示topology停止
2、编写Bolt
一些需要实现或覆写的重要方法:
(1)prepare:在Bolt启动前执行,提供Bolt启动环境配置。
3、在main方法进行提交topology
(1)execute:核心方法,Bolt每次从流接收一个订阅的tuple,都会调用这个方法
@Override
public void execute(Tuple tuple) {
// 使用 tuple.getString()或tuple.getStringByField()获取tuple中的内容
// String msg=tuple.getString(0);
String msg=tuple.getStringByField("test");
System.out.println("Bolt第"+count+"接受的消息:"+msg);
/**
*
* 没次调用处理一个输入的tuple,所有的tuple都必须在一定时间内应答。
* 可以是ack或者fail。否则,spout就会重发tuple。
* 如果基类有实现不需要手动应答
*/
// collector.ack(tuple);
}
(2)declareOutputFields:声明数据格式
(3)cleanup:在终止一个bolt之前会调用这个方法,用于bolt占用的资源
public static void main(String[] args) {
// TODO Auto-generated method stub
//定义一个拓扑
TopologyBuilder builder=new TopologyBuilder();
//设置一个Executeor(线程),默认一个
builder.setSpout(str1, new TestSpout());
//设置一个Executeor(线程),和一个task
builder.setBolt(str2, new TestBolt(),1).setNumTasks(1).shuffleGrouping(str1);
Config conf = new Config();
conf.put("test", "test");
try{
// 运行拓扑
if(args !=null&&args.length>0){ //有参数时,表示向集群提交作业,并把第一个参数当做topology名称
System.out.println("远程模式");
StormSubmitter.submitTopology(args[0], conf, builder.createTopology());
} else {//没有参数时,本地提交
// 启动本地模式
System.out.println("本地模式");
LocalCluster cluster = new LocalCluster();
cluster.submitTopology("111" ,conf, builder.createTopology() );
Thread.sleep(10000);
// 关闭本地集群
cluster.shutdown();
}
} catch(Exception e) {
e.printStackTrace();
}
}
4、运行
如果在Storm集群中进行使用,需要将程序打包为jar,将程序上传到storm集群中,输入:
storm jar xxx.jar xxx xxx
说明:第一个xxx是storm程序打包的包名,第二个xxx是运行主程序的路径,第三个xxx则表示主程序输入的参数,这个可以随意。