Apache Storm 的安装、配置及入门基础(二)

      本文翻译自:http://storm.apache.org/releases/current/Tutorial.html

      借鉴了:http://www.aboutyun.com/thread-7394-1-1.html

      过去十几年数据处理取得了飞速的发展,特别是 MapReduce,Hadoop及其相关技术以不可思议的程度来进行大规模存储和处理,但是这些处理技术不够实时,Hadoop 系统也无法变成一个实时系统,因为实时数据处理系统需求是完全不同于批处理系统的。

    但是业务需求却需要大规模实时数据处理,所以 Hadoop 就成为了数据处理生态系统中最大的一个短板。而Storm就弥补了这一不足。以前是人工建立网络队列和 worker 实时处理过程,所以存在严重的不足,比如数据队列冗长、系统易崩溃,也不适合大规模处理。现在 Storm极大地扩充了用例集、规模化、容错、数据不丢失等等特性,处理速度是非常快的。

一、Storm 基本构成部分

        如图1所示。Nimbus 是通过 zookeeper 来传递信息的,也就是 zookeeper 在 nimbus 和 worker 之间建立了协调关系,所以对于 Strom 来说,zookeeper 至关重要。

       早在 storm.yaml 配置中,我们定义supervisor.slots.ports: 有4个端口,这就是 worker 的工作端口,一个 supervisor 有4个 worker 端口。

    节点有两个: master 节点、 worker 节点。master节点运行 Nimbus服务,worker 节点运行 Supervisor服务。

    Nimbus 的作用:负责集群上的代码分配; 机器上的任务分配;监控失效数据

    Supervisor 的作用:监听分配的工作;启动、停止worker进程。每一个 worker 进程就是运行一个 topology 的子集;一个 正在运行的topology分布在集群上每个机器上运行的如图2所示。正在运行的topology你可以通过 UI web端查看到。


图2

    二、Topology 拓扑

        Topology是 Storm中很重要的概念,这是处理实时计算的核心概念。一个 Topology就是一个计算的拓扑图,就是计算的路径和节点构成,而且这个图还是封闭的哟!不会自动计算完毕的,你得使用 Storm kill 来杀掉这个执行的Topology。Topology就包含了处理逻辑,节点间的连接,也就是节点间的数据是怎么传递的。

       这个是运行的Topology:

      $ storm jar storm-starter-1.1.0.jar org.apache.storm.starter.ExclamationTopology ExclamationTopology

   三、Streams 数据流

        Storm 中核心抽象概念就是 Stream, 数据流就是大量的一系列的tuples(元组)。Storm 用基元(primitives)以一种分布式的、可靠的方式将一个数据流转换成一个新的数据流。比如,将一个微博数据流变换一个热门话题数据流。

        Storm 中提供的数据流转换基元就是 spout 和 bolt。spout 和 bolt 提供了对应的接口,实现这个接口就可以运行特定应用的逻辑。

         一个 spout就是一个数据流的源,例如,可以从 Kestrel(storm-kestrel 开源)队列中弹出的元组作为一个 spout,并可以将它们作为一个数据流。还有一个 spout可以调用 Twitter API 得到一个微博数据流。下面的一个图就表明了从一个源头取tuple元组形成一个 spout !就是从外部数据源(队列、数据库等)中读取数据,封装成元组,形成数据流。


bolt 是用来处理数据里的,可以对一些数据流(不只一个数据流)进行处理,可能会产生新的数据流。对一些复杂的数据流变换,比如从一个微博流中计算一个热门话题流,就需要很多步骤,因此就有多个 bolt。因此 bolt 中就有很多处理,比如运行函数,做流式聚合,流式链接,访问数据库等等。bolts 就如下图所示。

     

 从以上可以看出, spout 是一个 stream 的源, 而 bolt 却是处理输入的 streams,来产生新的 streams。注意,spout 和 bolt 只不过是流发生器而已。

 spout 和 bolt组成的网络就是拓扑图Topology,如下图所示。Topology就是最高层的逻辑抽象,可以直接送到 Storm 集群去执行。一个Topology图就是流式转换,每个节点是 spout 或者 bolt。图中的每条边就是 bolt 订阅了流,当一个 spout或者 bolt 产生一个元组到一个流时,它就发送元组到订阅了流的每个 bolt。



topology里面的每一个节点都是并行运行的。可以指定每个节点的并行度, storm则会在集群里面分配大量的线程计算。
一个topology会一直运行,直到你kill 掉它。storm能自动重新分配一些运行失败的任务, 并且storm保证不会有数据丢失, 即使一些机器意外停机并且消息被丢掉的情况下。

四、数据模型

       storm使用元组tuple来作为它的数据模型。每个tuple是一堆值,每个值有一个名字,并且每个值可以是任何类型, 在我的理解里面一个tuple可以看作一个没有方法的java对象。总体来看,storm支持所有的基本类型、字符串以及字节数组作为tuple的值类型。你也可以使用你自己定义的类型来作为值类型, 只要你实现对应的序列化器(serializer)。

一个Tuple代表数据流中的一个基本的处理单元,例如一条cookie日志,它可以包含多个Field,每个Field表示一个属性。

 
Tuple本来应该是一个Key-Value的Map,由于各个组件间传递的tuple的字段名称已经事先定义好了,所以Tuple只需要按序填入各个Value,所以就是一个Value List。
一个没有边界的、源源不断的、连续的Tuple序列就组成了Stream。
 

topology里面的每个节点必须定义它要产生的tuple的每个字段。 比如下面这个bolt定义它所产生的tuple包含两个字段,类型分别是: double和triple。

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方法定义要输出的字段 : ["double", "triple"]。这个bolt的其它部分我们接下来会解释。

发布了52 篇原创文章 · 获赞 4 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/caridle/article/details/76460995