Storm常用操作命令

1、任务提交命令:storm jar 【jar路径】 【拓扑包名.拓扑类名】 【拓扑名称】

storm jar /export/servers/storm/examples/storm-starter/storm-starter-topologies-1.0.3.jar org.apache.storm.starter.WordCountTopology  wordcount

与hadoop不同的是:不需要指定输入输出路径

hadoop jar /usr/local/wordcount.jar /data.txt /wcout

2、杀死任务命令:storm kill 【拓扑名称】 -w 10(执行kill命令时可以通过-w [等待秒数]指定拓扑停用以后的等待时间)

storm kill topology-name -w 10

3、停用任务命令:storm deactive  【拓扑名称】

storm deactive topology-name

我们能够挂起或停用运行中的拓扑。当停用拓扑时,所有已分发的元组都会得到处理,但是spouts的nextTuple方法不会被调用。销毁一个拓扑,可以使用kill命令。它会以一种安全的方式销毁一个拓扑,首先停用拓扑,在等待拓扑消息的时间段内允许拓扑完成当前的数据流。

4、启用任务命令:storm activate 【拓扑名称】

storm activate topology-name

5、重新部署任务命令:storm rebalance  【拓扑名称】

storm rebalance topology-name

再平衡使你重分配集群任务。这是个很强大的命令。比如,你向一个运行中的集群增加了节点。再平衡命令将会停用拓扑,然后在相应超时时间之后重分配worker,并重启拓扑。

StormWordCount(重点掌握)

WordCount分析:

Java版本:

1、读取文件中的数据,一行一行的读取;

2、将读到的数据进行切割;

3、对切割后的数组中的单词进行计算。

Hadoop版本:

1、按行读取文件中的数据;

2、在Mapper()函数中对每一行的数据进行切割,并输出切割后的数据数组;

3、接收Mapper()中输出的数据数组,在Reducer()函数中对数组中的单词进行计算,将计算后的统计结果输出。

Storm版本:

1、Spout从外部数据源中读取数据,随机发送一个元组对象出去;

2、SplitBolt接收Spout中输出的元组对象,将元组中的数据切分成单词,并将切分后的单词发射出去;

3、WordCountBolt接收SplitBolt中输出的单词数组,对里面单词的频率进行累加,将累加后的结果输出。

StormWordCount代码实现及分析(重点掌握)

在IDEA中创建一个Maven项目,先在pom.xml添加依赖--->import changes

创建Maven项目步骤:

使用IDEA编辑器创建一个Maven项目
前提:假设您已经安装好了IDEA编辑器,由于编辑器自带Maven插件,不需要单独安装maven。当然IDEA本身是支持安装外部的maven的。
1、打开编辑器
笔者使用的是14.1 不是当前最新编辑器
2、创建maven项目第一步:
依次点击软件左上角的File->new->project
然后选择maven,并点击next。在这一步有一个需要注意的地方,就是为你的项目选择JDK或者SDK.如果您之前没有配置过JDK,可以点击new按钮,设置您JDK的home目录。
3、填写maven项目的groupid,和artifactid。然后点击下一步
一般来讲,groupid写您的公司及部门或项目的名称,比如:com.ahu
artifactid写您的子项目或者子模块的名字,比如当前项目是创建maven项目,我们可以将artifactid写成:stormwordcount
version可以不用修改
4、填写项目名称及指定项目所在的目录
projectName:StormWordCount
location:任意地址---->比如:E:\StormWordCount
至此,创建maven项目完毕。

     <dependencies>
<dependency>
<groupId>org.apache.storm</groupId>
<artifactId>storm-core</artifactId>
<version>0.9.5</version>
<!-- <scope>provided</scope>-->
</dependency>
</dependencies>

然后在写相关代码:

项目主要流程:

 package com.ahu.storm;

 import backtype.storm.Config;
import backtype.storm.LocalCluster;
import backtype.storm.StormSubmitter;
import backtype.storm.generated.AlreadyAliveException;
import backtype.storm.generated.InvalidTopologyException;
import backtype.storm.topology.TopologyBuilder;
import backtype.storm.tuple.Fields; /**
* Created by ahu_lichang on 2017/5/18.
*/
public class WordCountTopologyMain {
public static void main(String[] args) throws AlreadyAliveException, InvalidTopologyException {
//1、准备一个TopologyBuilder
//storm框架支持多语言,在Java环境下创建一个拓扑,需要使用TopologyBuilder
TopologyBuilder topologyBuilder = new TopologyBuilder();
//MySpout类,在已知的英文句子中,所及发送一条句子出去
topologyBuilder.setSpout("mySpout", new MySpout(), 2);
//MySplitBolt类,主要是将一行一行的文本内容切割成单词
topologyBuilder.setBolt("mybolt1", new MySplitBolt(), 2).shuffleGrouping("mySpout");
//MyCountBolt类,负责对单词的频率进行累加
topologyBuilder.setBolt("mybolt2", new MyCountBolt(), 4).fieldsGrouping("mybolt1", new Fields("word"));
/**
* i
* am
* lilei
* love
* hanmeimei
*/
//2、创建一个configuration,用来指定当前topology 需要的worker的数量
//启动topology的配置信息
Config config = new Config();
//定义你希望集群分配多少个工作进程给你来执行这个topology
config.setNumWorkers(2); //3、提交任务 -----两种模式 本地模式和集群模式
//这里将拓扑名称写死了mywordcount,所以在集群上打包运行的时候,不用写拓扑名称了!也可用arg[0]
StormSubmitter.submitTopology("mywordcount", config, topologyBuilder.createTopology());
//LocalCluster localCluster = new LocalCluster();
//localCluster.submitTopology("mywordcount",config,topologyBuilder.createTopology());
}
}

MySpout的实现及生命周期:

 package com.ahu.storm;

 import backtype.storm.spout.SpoutOutputCollector;
import backtype.storm.task.TopologyContext;
import backtype.storm.topology.OutputFieldsDeclarer;
import backtype.storm.topology.base.BaseRichSpout;
import backtype.storm.tuple.Fields;
import backtype.storm.tuple.Values; import java.util.Map; /**
* Created by ahu_lichang on 2017/5/18.
*/
public class MySpout extends BaseRichSpout {
//用来收集Spout输出的Tuple
SpoutOutputCollector collector; //初始化方法
public void open(Map conf, TopologyContext context, SpoutOutputCollector collector) {
this.collector = collector;
} //storm 框架在 while(true) 调用nextTuple方法
public void nextTuple() {
collector.emit(new Values("i am lilei love hanmeimei"));
} //消息源可以发射多条消息流stream.多条消息流可以理解为多种类型的数据
public void declareOutputFields(OutputFieldsDeclarer declarer) {
declarer.declare(new Fields("sentence"));
}
}

MySplitBolt的实现及生命周期:

 package com.ahu.storm;

 import backtype.storm.task.OutputCollector;
import backtype.storm.task.TopologyContext;
import backtype.storm.topology.OutputFieldsDeclarer;
import backtype.storm.topology.base.BaseRichBolt;
import backtype.storm.tuple.Fields;
import backtype.storm.tuple.Tuple;
import backtype.storm.tuple.Values; import java.util.Map; /**
* Created by ahu_lichang on 2017/5/18.
*/
public class MySplitBolt extends BaseRichBolt {
OutputCollector collector; //初始化方法
public void prepare(Map stormConf, TopologyContext context, OutputCollector collector) {
this.collector = collector;
} // 被storm框架 while(true) 循环调用 传入参数tuple
//input内容是句子,execute方法将句子切割成单词发出
public void execute(Tuple input) {
String line = input.getString(0);
String[] arrWords = line.split(" ");
for (String word : arrWords) {
collector.emit(new Values(word, 1));
}
} public void declareOutputFields(OutputFieldsDeclarer declarer) {
declarer.declare(new Fields("word", "num"));
}
}

MyCountBolt的实现及生命周期:

 package com.ahu.storm;

 import backtype.storm.task.OutputCollector;
import backtype.storm.task.TopologyContext;
import backtype.storm.topology.OutputFieldsDeclarer;
import backtype.storm.topology.base.BaseRichBolt;
import backtype.storm.tuple.Tuple; import java.util.HashMap;
import java.util.Map; /**
* Created by ahu_lichang on 2017/5/18.
*/
public class MyCountBolt extends BaseRichBolt {
OutputCollector collector;
//用来保存最后计算的结果key=单词,value=单词个数
Map<String, Integer> map = new HashMap<String, Integer>(); public void prepare(Map stormConf, TopologyContext context, OutputCollector collector) {
this.collector = collector;
} public void execute(Tuple input) {
String word = input.getString(0);
Integer num = input.getInteger(1);
System.out.println(Thread.currentThread().getId() + " word:" + word);
if (map.containsKey(word)) {
Integer count = map.get(word);
map.put(word, count + num);
} else {
map.put(word, num);
}
System.out.println("count:" + map);
} public void declareOutputFields(OutputFieldsDeclarer declarer) {
//不输出
}
}

两种运行模式:

1、本地模式:直接在IDEA中的WordCountTopologyMain运行即可在控制台观察到输出结果

2、集群模式:

要打包运行。打包方法:

将jar包上传到storm1上,去运行storm /root/stormwordcount.XXXX.jar  com.ahu.storm.WordCountTopologyMain

注意:这样打包运行的时候,会出错:NoClassDefFoundError: backtype/storm/topology/IRichSpout

这是因为打包的时候,有的jar包没有打到里面去,打包方式不对!需要在pom.xml指定一个Build,指定打包的方式,将所有的依赖都打成jar。

     <build>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<!-- <archive>
<manifest>
<mainClass>com.ahu.storm.hadoop.mapreduce.wordcount.WordCount</mainClass>
</manifest>
</archive>-->
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>

这样再打包运行,就不会出错了!运行成功后,可以在worker运行的机器上查看日志:/export/servers/storm/logs/下查看,tail -100f worker-6701.log.1

Storm具体的任务执行流程图

Stream Grouping详解

Storm里面有7种类型的stream grouping

l Shuffle Grouping: 随机分组, 随机派发stream里面的tuple,保证每个bolt接收到的tuple数目大致相同。

l Fields Grouping:按字段分组,比如按userid来分组,具有同样userid的tuple会被分到相同的Bolts里的一个task,而不同的userid则会被分配到不同的bolts里的task。

l All Grouping:广播发送,对于每一个tuple,所有的bolts都会收到。

l Global Grouping:全局分组, 这个tuple被分配到storm中的一个bolt的其中一个task。再具体一点就是分配给id值最低的那个task。

l Non Grouping:不分组,这stream grouping个分组的意思是说stream不关心到底谁会收到它的tuple。目前这种分组和Shuffle grouping是一样的效果, 有一点不同的是storm会把这个bolt放到这个bolt的订阅者同一个线程里面去执行。

l Direct Grouping: 直接分组, 这是一种比较特别的分组方法,用这种分组意味着消息的发送者指定由消息接收者的哪个task处理这个消息。只有被声明为Direct Stream的消息流可以声明这种分组方法。而且这种消息tuple必须使用emitDirect方法来发射。消息处理者可以通过TopologyContext来获取处理它的消息的task的id (OutputCollector.emit方法也会返回task的id)。

Local or shuffle grouping:如果目标bolt有一个或者多个task在同一个工作进程中,tuple将会被随机发生给这些tasks。否则,和普通的Shuffle Grouping行为一致。

Storm常用操作命令及WordCount的更多相关文章

  1. 【转载】Linux中常用操作命令

    说明:开始学习linux系统,为了方便查看,特转载一篇Linux中常用操作命令,转载地址:http://www.cnblogs.com/laov/p/3541414.html 正文: Linux简介及 ...

  2. Git常用操作命令与图解

    Git 是一个很强大的分布式版本控制系统.它不但适用于管理大型开源软件的源代码,管理私人的文档和源代码也有很多优势. Git常用操作命令: 1) 远程仓库相关命令 检出仓库:$ git clone g ...

  3. svn 常用操作命令

    svn 常用操作命令 检出 svn checkout http://路径(目录或文件的全路径) [本地目录全路径] --username 用户名 svn checkout svn://路径(目录或文件 ...

  4. MongoDB(1):常用操作命令大全

    MongoDB常用操作命令大全(转) http://www.jb51.net/article/48217.htm 成功启动MongoDB后,再打开一个命令行窗口输入mongo,就可以进行数据库的一些操 ...

  5. hadoop常用操作命令

    #############centos6.8IP常用操作命令#######################DEVICE=eth0TYPE=EthernetONBOOT=yesNM_CONTROLLED ...

  6. 2018.4.23 git常用操作命令收集(转)

    Git常用操作命令收集: 1. 远程仓库相关命令 检出仓库:$ git clone git://github.com/jquery/jquery.git 查看远程仓库:$ git remote -v ...

  7. HBase常用操作命令

    HBase常用操作命令 1.进入HBase脚本客户端 #hbase shell #进入HBase脚本客户端 > whoami    #查看当前登录用户 > status           ...

  8. liunx vim常用操作命令

    vim常用操作命令 vim abc // 打开该文件,或者新建文件 vim +3 abc // 打开文件并跳转到第三行 vim +/hello //打开文件并跳转到第一次出现hello的位置 vim ...

  9. linLINUX中常用操作命令

    LINUX中常用操作命令 Linux简介及Ubuntu安装 常见指令 系统管理命令 打包压缩相关命令 关机/重启机器 Linux管道 Linux软件包管理 vim使用 用户及用户组管理 文件权限管理 ...

随机推荐

  1. 【题解】 bzoj1911: [Apio2010]特别行动队 (动态规划+斜率优化)

    bzoj1911,懒得复制,戳我戳我 Solution: 线性DP(打牌) \(dp\)方程还是很好想的:\(dp[i]=dp[j-1]+a*(s[i]-s[j-1])^2+b*(s[i]-s[j-1 ...

  2. Linux下修改tomcat内存

    由于服务器上放的tomcat太多,造成内存溢出. 常见的内存溢出有以下两种: java.lang.OutOfMemoryError: PermGen space java.lang.OutOfMemo ...

  3. 界面编程之QT的数据库操作20180801

    /*******************************************************************************************/ 一.数据库连 ...

  4. opencv ---getRotationMatrix2D函数

    getRotationMatrix2D函数 主要用于获得图像绕着 某一点的旋转矩阵  Mat getRotationMatrix2D(Point2f center, double angle, dou ...

  5. sso接口的调用

    之前一直想sso接口已经写好了,登录注册功能是怎么调用的呢?原来在登录注册的jsp页面实现的接口的调用,页面的校验和验证功能在jsp页面即可实现. 注册页面: <%@ page language ...

  6. VBA:Double类型与Decimal类型

    Sub DataType() For i = 0 To 100 t1 = t1 + 0.1 t2 = t2 + CDec(0.1) Debug.Print "Double=" &a ...

  7. MySQL记录异常实体类设计

    public class LogInfo { /// <summary> /// 应用名 /// </summary> public string AppName { get; ...

  8. AngularJS入门基础——控制器

    AngularJS中的控制器是一个函数,用来向视图的作用域添加额外的功能.我们用它来给作用域对象设置初始状态,并添加自定义行为. AngularJS同其他JavaScript框架最主要的一个区别就是, ...

  9. Xcode多种Build Configuration配置使用

    Build Configuration? Xcode默认会有2个编译模式,一个是Debug,一个是Release.Release下不能调试程序,编译时有做编译优化,会比用Debug打包出来的运行快,另 ...

  10. Anaconda+django写出第一个web app(九)

    今天来学习外键的使用,用外键来连接数据库中的两个表. 当我们的tutorials非常多的时候,目前的显示方式就会使得页面非常凌乱.我们可以考虑把这些教程分为不同的系列,页面只显示标题以及概要等信息,进 ...