storm初识

Storm集群的组成

strom集群与hadoop集群表面上看还是很相似的。例如:在hadoop上你运行"MapReduce jobs",而在storm上运行的是"topologies"。"Jobs"和"topologies"是不一样的--一个主要的差别就是MapReduce job最终会运行完成并结束,而topology将会不停的运转来处理源源不断的流数据。(除非我们手动的kill进程,否则topology将一直运行)。

在Storm集群中有两类节点:master node 以及 worker nodes。 master node运行一个守护进程"Nimbus"跟Hadoop中的''JobTracker'比较类似。Nimbus在集群中主要负责分发任务以及进行监控。

每个worker node运行一个守护进程"Supervisor"。supervisor监听任务是否分发到本机器,并负责启动和停止由Nimbus分发来的worker处理程序。每个worker处理程序执行topology的一部分子集。一个运行中的topology由多个分布在多台机器上的worker processes组成。

由图可以看到,Nimbus与Supervisors之间的协调由zookeeper来负责。另外,Nimbus与Supervisor都是采用的fail-fast机制并且是无状态的。所有的状态均由zookeeper保存或者放在本地磁盘上。这意味着你可以使用kill -9 Nimbus 或者 Supervisors,然后Storm又会启动他们相应的备份,不受任何影响。这种设计方式使得Storm集群十分的稳定。


Topologies(拓扑)

要在storm上进行实时计算,我们需要创建"topoogies"。一个topology是一个计算的图结构。topology中的每个节点都包含着程序处理逻辑,节点间的连线显示了数据在节点间的传输路径。

要运行一个topology很简单,按照下面的格式就行:

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

all-my-code是一个整体的编好的topology的jar包,backtype.storm.MyTopology是该jar包的入口类,arg1 arg2为相应的入口函数的参数。


Streams(流)

在Storm中一个主要的概念就是"stream"。一个stream是一连串的无穷尽的tuples(元组)。Storm以一种分布式、可靠的方式将一个原始的stream变成我们想要的stream。例如:我们可以利用storm将tweet的原始stream转换成我们所需要的流行词的stream。

在进行stream转换上,Storm提供了"spouts"与"bolts"两种接口。我们可以通过这两种接口来实现我们自己特定的stream转换的逻辑。

spout即为stream的源头,spout通过读取原始数据(可能来源于kafka 或者 Kestrel queue)并将其以stream的形式发出。或者 spout可以连接Twitter API并发出tweets的stream。

bolt消费任意数量的输入streams,并进行相应处理,而且可能产生新的streams。bolts可以进行很多的操作如:运行函数,过滤tuples,进行stream汇聚,与数据库连接等待。


spouts与bolts连接成的结构即为topology。显然topology是一种有向无环的结构。


在Storm topology中的每个节点都是可以进行并发的。我们可以自行设置每个节点的并发数。Storm将会生成相应数量的线程执行并发。

跟前面提到过的一样,topology将会一直执行,除非你手动kill掉。Storm也会自动的重新分配任何失败的任务。Storm保证不会有数据丢失。


Data model(数据模型)

Storm使用tuples(元组)来做数据模型。tuple就是一个被命名了的值列表。tuple的字段(field)可以是任意类型的对象。Storm支持原始类型、strings以及byte数组来做tuple的字段值。如果我们要使用其他的类型,我们需要对该类型实现序列化(serializer

topology中的每个节点都需要为其发出的tuples声明输出字段。例如:bolt 声明它发送了 一个字段为"double","triple"的2元组:

public class DoubleAndTripleBolt extends BaseRichBolt {
    private OutputCollectorBase _collector;

    @Override
    public void prepare(Map conf, TopologyContext context, OutputCollectorBase collector) {
        _collector = collector;
    }

    @Override
    public void execute(Tuple input) {
        int val = input.getInteger(0);        
        _collector.emit(input, new Values(val*2, val*3));
        _collector.ack(input);
    }

    @Override
    public void declareOutputFields(OutputFieldsDeclarer declarer) {
        declarer.declare(new Fields("double", "triple"));
    }    
}
declareOutputFields函数声明了tuple的值对应的字段。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值