简介
Storm是一个免费开源、分布式、高容错的实时计算系统。Storm令持续不断的流计算变得容易,弥补了Hadoop批处理所不能满足的实时要求。Storm经常用于在实时分析、在线机器学习、持续计算、分布式远程调用和ETL等领域。Storm的部署管理非常简单,而且,在同类的流式计算工具,Storm的性能也是非常出众的。
Jstorm是阿里巴巴的一个基于storm原理开发的纯java实时处理,比storm更快,更强,更稳定。
基本概念
1.元组(tuple)
在python也有元组但是python的元组和我们Storm中的元组不是一个概览,我们这里的元组是只我们的基本传输单位,我们把元组支持所有的基本类型和我们自己所自定义的类型。由于我们传一个值可能不够,需要多个,这个时候就需要一个Map来存储key,value的值了在我们的storm中我们可以预先定义,比如在jstorm中
public void declareOutputFields(OutputFieldsDeclarer outputFieldsDeclarer) {
outputFieldsDeclarer.declare(new Fields("test1","test2"));
}
我们定义了元组的字段名称为test1和test2,这个时候需要我们按照顺序存储,比如new Values(1,2);这里1对应的就是test1字段,2对应的就是test2的字段,类似一个key,value的对应关系。
2.流(Stream)
我们想象元组是水滴,而我们的流就是由无数水滴组成的流。我们的流是由元组组成。在storm中分组我们也可以按照流不同来进行流的合并和划分,void declareStream(String var1, Fields var2);
在tuple中也可以获得是哪个流:tuple.getSourceStreamId()
。在流中有两个比较关键的元素,Spout和bolt。
Spout顾名思义就是水龙头,也就是我们的源头,我们通过Spout可以读取MQ中的信息,转换成合适的元组,然后发射到我们的拓扑中。
Bolt接受任何数量的输入流,执行处理后,也可以发射元组到新的bolt中。
当然我们同样也可以不声明流的ID,这里我们就使用默认的id值
3.spout
上面已经提到了Spout是我们拓扑流的来源,是一个拓扑中产生数据流的组件。通常情况下,Spout会从外部数据源读取数据,然后转换成拓扑内部的源数据。在Spout中有两种模式一种是可靠的,另外一种是不可靠的。具体我们使用ack和fail机制来完成可靠实现。
在Storm中ack,fail,nextTuple是在一条线程,这里出现了一个问题要是全是空数据 也就是队列中没有数据怎么办,我们还一直调用nextTuple()吗?这时我们可以考虑阻塞nextTuple(),但是还有ack,fail等怎么办呢你也要把他们阻塞呢?所以Jstorm采取了给ack开了一个新的线程,nextTuple()就自己一个线程,这个时候就可以给nextTuple()阻塞。
4.Bolt闪电
我们在拓扑中的所有处理都在Bolt中完成,Bolt是流的处理节点,从一个拓扑接收数据,然后执行进行处理的组件。Bolt可以完成过滤,业务处理,连接运算等等操作。Bolt是一个被动的角色,只有上流与水源来了之后才能执行。
一般在我们的应用中一个bolt可以做一个简单的转换,如果需要复杂的转换就需要多个转换。在bolt中我们也可以发出多个流,使用declareStream()方法声明多个流,并使用OutputCollector类的emit()方法指定发射的流。
在bolt中我们也可以自己指定订阅什么流,在bolt中的主要方法是execute()方法,该方法将一个新的元祖作为输入。Bolt使用OutputCollector发射新的元组。Bolt必须为他们处理的每个元组调用ack()方法,当然这也不是必须,我们可以使用IBasicBolt,对ack我们可以不作操作,对于fail我们可以使用throw new FailException。
5拓扑
拓扑就是我们在Storm中运行的程序了,因为各个组件间的消息流动而形成逻辑上的拓扑结构。把实时应用程序的运行逻辑打成jar包后提交到Storm的拓扑。Storm的拓扑是一个7*24小时运行的作业,除非你把他杀死。
6主控节点与工作节点
Storm集群有两个节点:主控和工作。主控只能有一个,工作有多个。
7Nimbus进程和Supervisor进程
主控节点运行一个为Nimus的守护进程,负责在集群中分发代码,对应节点分派任务,监视故障。
每个工作节点运行一个成为Supervisor的守护进程。用来坚挺主机上已经分配的主机作业。
8Worker工作进程
Worker是是Spout中具体处理逻辑的进程。
9Executor
一个Worker有多个Executor,代表一个线程。
10Task
代表一个任务,一个Executor有多个Task