Storm从源码安装以及初步运行

Posted by AlstonWilliams on February 17, 2019

由于项目需要对Storm进行进一步开发,所以就研究了一下Storm.拿到源代码之后,先是手动编译了一下,再运行了一个demo尝试了一下.

编译Storm

没想到光是手动编译就花费了不少时间.

最终,写了一个脚本帮助编译:

# !/bin/bash
mvn clean package install -DskipTests=true 
&& cd storm-dist/binary 
&& mvn package -Dgpg.skip=true
&& cp target/apache-storm-1.1.0.tar.gz ~/source_code/apache-storm-1.1.0/compiled 
&& cd  ~/source_code/apache-storm-1.1.0/compiled 
&& tar zxvf apache-storm-1.1.0.tar.gz

运行此脚本需要你先进入到storm所在的目录.

这里我在storm所在的目录下新建了一个目录,compiled.这个目录中,存放经过编译后可以真正运行的storm.各位可以根据自己的情况进行修改.

这样编译完了storm并设置好环境变量之后,就可以运行storm了,我设置的环境变量如下:

export STORM_HOME=/home/alstonwilliams/source_code/apache-storm-1.1.0/compiled/apache-storm-1.1.0
export STORM_CLASSPATH=${STORM_HOME}/lib

export CLASSPATH=.:${STORM_CLASSPATH}
export PATH=${STORM_HOME}/bin:$PATH

Storm中,需要用ZooKeeper来管理状态信息等元数据,所以我们还需要安装ZooKeeper.ZooKeeper我们不需要从源码安装,直接从官网下载下来并注意设置好环境变量即可.然后通过下面的命令启动ZooKeeper:

your_ZooKeeper_installation/bin/zkServer.sh start

然后可以通过下面的命令查看是否启动成功:

your_ZooKeeper_installation/bin/zkCli.sh

安装好ZooKeeper之后,我们还需要为Storm进行配置,在directory_which_contains_storm_after_compiling/conf目录中,新建文件storm.yaml,写入下面的配置:

storm.zookeeper.servers:
  - "localhost"

storm.local.dir: "/home/alstonwilliams/source_code/apache-storm-1.1.0/data"

nimbus.host: "localhost"

supervisor.slots.ports:
  - 6700
  - 6701
  - 6702
  - 6703

上面的配置文件,设置了ZooKeeper所在的主机,Storm的数据目录,Supervisor的端口.你可以根据自己的需要进行修改.更多参数请查看Storm官方文档.

然后就可以通过下面的命令分别启动nimbus, supervisor:

storm nimbus
storm supervisor

写个Demo试试

终于启动起来Storm了.我们还要写个demo跑一下试试.

这里不给出demo的代码了,各位感兴趣的话,自己去Tutorials这个网站上自己看吧,对应的网址是:https://www.tutorialspoint.com/apache_storm/apache_storm_working_example.htm.不过这个网站可能会被墙,即使没有被墙,打开速度可能也会挺慢.

终于把Demo写完了.运行mvn package打包一下,再用java -jar target/demo.jar运行一下试试,这时你会遇到no main manifest attribute错误.

这是因为mvn package之后得到的jar包,并不是一个可运行的jar包,其中缺少了依赖,以及一些必要的文件.在pom.xml中,添加下面的Snippet:

    <build>
        <plugins>
            <!-- any other plugins -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-assembly-plugin</artifactId>
                <version>2.4.1</version>
                <configuration>
                    <descriptorRefs>
                        <descriptorRef>jar-with-dependencies</descriptorRef>
                    </descriptorRefs>
                    <archive>
                        <manifest>
                            <mainClass>com.projecthome.LogAnalyserStorm</mainClass>
                        </manifest>
                    </archive>
                </configuration>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>single</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

将其中的mainClass部分换成你的主类的完全限定类名.然后,再用mvn package一下,你能在target目录下,看到两个jar文件,一个是demo.jar,另一个是demo-jar-with-dependencies.jar.在demo-jar-with-dependencies中,包含了需要的依赖.

现在,你就可以通过java -jar demo-jar-with-dependencies.jar命令来启动单机版Storm并查看结果了.

好,上面我们知道了如何在开发模式下运行Storm Demo了.但是,我们开发完之后,要提交到Storm集群上运行吧.而上面我们只是让Demo在本地运行,其实在本地运行的话,你不需要安装Storm和ZooKeeper也是可以的.那么我们应该如何来做呢?

将和LocalCluster相关的部分,换成StormSubmitter.

比如:

public class LogAnalyserStorm {

  public static void main(String[] args) throws Exception{
    Config config = new Config();
    config.setDebug(true);

    TopologyBuilder builder = new TopologyBuilder();
    builder.setSpout("call-log-reader-spout", new FakeCallLogReaderSpout());

    builder.setBolt("call-log-creator-bolt", new CallLogCreatorBolt())
            .shuffleGrouping("call-log-reader-spout");
    builder.setBolt("call-log-counter-bolt", new CallLogCounterBolt())
            .fieldsGrouping("call-log-creator-bolt", new Fields("call"));

//    LocalCluster cluster = new LocalCluster();
//    cluster.submitTopology("LogAnalyserStorm", config, builder.createTopology());

    StormSubmitter.submitTopology("LogAnalyserStorm", config, builder.createTopology());

//    Thread.sleep(10000);

//    cluster.shutdown();

  }

}

然后使用mvn package构建一下.然后上传jar文件并在Storm集群上通过storm jar demo.jar your_main_class_fqdn需要注意的是,上传的时候,要上传那个不包含storm-core依赖的jar包.在我们的demo中,就是上传那个demo.jar.因为如果上传demo-jar-with-dependencies.jar,会由于Storm集群上本身已经存在Storm-core.jar包并且包含了相同的defaults.yaml文件,而运行失败.

当然,在实际开发中,我们还可能依赖其他的包,这时候,我们可以通过在pom.xml中,将storm-core这个依赖的scope设置为provided,让其在打包时不要包含storm-core这个依赖.然后上传demo-jar-with-dependencies.jar