storm两个案例(1单词计数本地执行 2累加集群执行 3集群关闭storm任务写法)

来源:互联网 发布:手机网络不卡玩游戏卡 编辑:程序博客网 时间:2024/06/07 12:55

1 如何监听到文件夹内新增了文件

2 如何监听到原文件内容数据做了变更

3 为了有两个bolt 一个用于切分  一个用于统计单词个数 为何不写在一起呢??

    每一个组件完成单独功能  执行速度非常快  并且提高每个组件的并行度已达到单位时间内处理数据更大

4 参考flume ng 对处理过的文件做修改, 这里是将处理过的文件后缀更改达到目的

 

 操作图如下:



 

 

 2 单词计数代码:

Java代码  收藏代码
  1. package changping.houzhihoujue.storm;  
  2.   
  3. import java.io.File;  
  4. import java.io.IOException;  
  5. import java.util.Collection;  
  6. import java.util.HashMap;  
  7. import java.util.List;  
  8. import java.util.Map;  
  9. import java.util.Map.Entry;  
  10.   
  11. import org.apache.commons.io.FileUtils;  
  12.   
  13. import backtype.storm.Config;  
  14. import backtype.storm.LocalCluster;  
  15. import backtype.storm.spout.SpoutOutputCollector;  
  16. import backtype.storm.task.OutputCollector;  
  17. import backtype.storm.task.TopologyContext;  
  18. import backtype.storm.topology.OutputFieldsDeclarer;  
  19. import backtype.storm.topology.TopologyBuilder;  
  20. import backtype.storm.topology.base.BaseRichBolt;  
  21. import backtype.storm.topology.base.BaseRichSpout;  
  22. import backtype.storm.tuple.Fields;  
  23. import backtype.storm.tuple.Tuple;  
  24. import backtype.storm.tuple.Values;  
  25. import backtype.storm.utils.Utils;  
  26.   
  27. /** 
  28.  * 作业:实现单词计数。 
  29.  *     (1)要求从一个文件夹中把所有文件都读取,计算所有文件中的单词出现次数。 
  30.  *     (2)当文件夹中的文件数量增加是,实时计算所有文件中的单词出现次数。 
  31.  */  
  32. public class MyWordCountTopology {  
  33.   
  34.      // 祖品火车 创建轨道 发车流程  
  35.      public static void main( String[] args ) {  
  36.             String DATASOURCE_SPOUT = DataSourceSpout.class.getSimpleName();  
  37.             String SPLIT_BOLD = SplitBolt.class.getSimpleName();  
  38.             String COUNT_BOLT = CountBolt.class.getSimpleName();  
  39.               
  40.             final TopologyBuilder builder = new TopologyBuilder();  
  41.             builder.setSpout(DATASOURCE_SPOUT, new DataSourceSpout());  
  42.             builder.setBolt(SPLIT_BOLD, new SplitBolt()).shuffleGrouping(DATASOURCE_SPOUT);  
  43.             builder.setBolt(COUNT_BOLT, new CountBolt()).shuffleGrouping(SPLIT_BOLD);  
  44.               
  45.             final LocalCluster localCluster = new LocalCluster();  
  46.             final Config config = new Config();  
  47.             localCluster.submitTopology(MyWordCountTopology.class.getSimpleName(), config, builder.createTopology());  
  48.             Utils.sleep(9999999);  
  49.             localCluster.shutdown();  
  50.      }  
  51.       
  52. }  
  53. // 数据源  
  54. class DataSourceSpout extends BaseRichSpout{  
  55.   
  56.     private Map conf;  
  57.     private TopologyContext context;  
  58.     private SpoutOutputCollector collector;  
  59.       
  60.     public void open(Map conf, TopologyContext context,SpoutOutputCollector collector) {  
  61.         this.conf = conf;  
  62.         this.context = context;  
  63.         this.collector = collector;  
  64.     }  
  65.   
  66.     public void nextTuple() {  
  67.         // 过滤文件夹D:/father 得到以txt结尾的文件  
  68.         Collection<File> files = FileUtils.listFiles(new File("D:/father"), new String[]{"txt"}, true);  
  69.         if(files != null && files.size() > 0){  
  70.             for(File file : files){  
  71.                 try {// 将文件每一行都发射到 bolt内  
  72.                     List<String> lines = FileUtils.readLines(file);  
  73.                     for(String line : lines){  
  74.                         collector.emit(new Values(line));  
  75.                     }  
  76.                     //修改操作完的文件(这里是修改后缀) 这样nextTuple方法就不会再重新处理该文件  
  77.                     FileUtils.moveFile(file, new File(file.getAbsolutePath() + "." + System.currentTimeMillis()));  
  78.                 } catch (IOException e) {  
  79.                     e.printStackTrace();  
  80.                 }  
  81.             }  
  82.               
  83.         }  
  84.     }  
  85.   
  86.     public void declareOutputFields(OutputFieldsDeclarer declarer) {  
  87.         declarer.declare(new Fields("line"));  
  88.     }  
  89.       
  90. }  
  91. // 切分单词逻辑  
  92. class SplitBolt extends BaseRichBolt{  
  93.   
  94.     private Map conf;  
  95.     private TopologyContext context;  
  96.     private OutputCollector collector;  
  97.       
  98.     public void prepare(Map stormConf, TopologyContext context, OutputCollector collector) {  
  99.         this.conf = stormConf;  
  100.         this.context = context;  
  101.         this.collector = collector;  
  102.     }  
  103.   
  104.     public void execute(Tuple input) {  
  105.         String line = input.getStringByField("line");  
  106.         String[] words = line.split("\\s");  
  107.         for(String word : words){ // 发送每一个单词  
  108.             System.err.println(word);  
  109.             collector.emit(new Values(word));  
  110.         }  
  111.     }  
  112.   
  113.     public void declareOutputFields(OutputFieldsDeclarer declarer) {  
  114.         declarer.declare(new Fields("word"));  
  115.     }  
  116.       
  117. }  
  118.   
  119. //统计单词逻辑  
  120. class CountBolt extends BaseRichBolt{  
  121.   
  122.     private Map stormConf;  
  123.     private TopologyContext context;  
  124.     private OutputCollector collector;  
  125.     public void prepare(Map stormConf, TopologyContext context,OutputCollector collector) {  
  126.         this.stormConf = stormConf;  
  127.         this.context = context;  
  128.         this.collector = collector;  
  129.     }  
  130.   
  131.     private HashMap<String, Integer> map = new  HashMap<String, Integer>();  
  132.     public void execute(Tuple input) {  
  133.         String word = input.getStringByField("word");  
  134.         System.err.println(word);  
  135.         Integer value = map.get(word);  
  136.         if(value==null){  
  137.             value = 0;  
  138.         }  
  139.         value++;  
  140.         map.put(word, value);  
  141.         //把结果写出去  
  142.         System.err.println("============================================");  
  143.         Utils.sleep(2000);  
  144.         for (Entry<String, Integer> entry : map.entrySet()) {  
  145.             System.out.println(entry);  
  146.         }  
  147.     }  
  148.   
  149.     public void declareOutputFields(OutputFieldsDeclarer declarer) {  
  150.           
  151.     }  
  152.       
  153. }  
  154. /*class CountBolt extends BaseRichBolt{ 
  155.     private Map conf; 
  156.     private TopologyContext context; 
  157.     private OutputCollector collector; 
  158.      
  159.     public void prepare(Map conf, TopologyContext context, OutputCollector collector) { 
  160.         this.conf = conf; 
  161.         this.context = context; 
  162.         this.collector = collector; 
  163.     } 
  164.      
  165.     *//** 
  166.      * 对单词进行计数 
  167.      *//* 
  168.      
  169.     Map<String, Integer> countMap = new HashMap<String, Integer>(); 
  170.     public void execute(Tuple tuple) { 
  171.         //读取tuple 
  172.         String word = tuple.getStringByField("word"); 
  173.         //保存每个单词 
  174.         Integer value = countMap.get(word); 
  175.         if(value==null){ 
  176.             value = 0; 
  177.         } 
  178.         value++; 
  179.         countMap.put(word, value); 
  180.         //把结果写出去 
  181.         System.err.println("============================================"); 
  182.         Utils.sleep(2000); 
  183.         for (Entry<String, Integer> entry : countMap.entrySet()) { 
  184.             System.out.println(entry); 
  185.         } 
  186.     } 
  187.  
  188.     public void declareOutputFields(OutputFieldsDeclarer arg0) { 
  189.          
  190.     } 
  191.  
  192. }*/  

 

 

 

3 集群运行累加写法:

 

Java代码  收藏代码
  1. package changping.houzhihoujue.storm;  
  2.   
  3. import java.io.File;  
  4. import java.io.IOException;  
  5. import java.util.HashMap;  
  6. import java.util.List;  
  7. import java.util.Map;  
  8. import java.util.concurrent.TimeUnit;  
  9.   
  10. import org.apache.commons.io.FileUtils;  
  11.   
  12. import ch.qos.logback.core.util.TimeUtil;  
  13.   
  14. import backtype.storm.Config;  
  15. import backtype.storm.LocalCluster;  
  16. import backtype.storm.StormSubmitter;  
  17. import backtype.storm.spout.SpoutOutputCollector;  
  18. import backtype.storm.task.OutputCollector;  
  19. import backtype.storm.task.TopologyContext;  
  20. import backtype.storm.topology.OutputFieldsDeclarer;  
  21. import backtype.storm.topology.TopologyBuilder;  
  22. import backtype.storm.topology.base.BaseRichBolt;  
  23. import backtype.storm.topology.base.BaseRichSpout;  
  24. import backtype.storm.tuple.Fields;  
  25. import backtype.storm.tuple.Tuple;  
  26. import backtype.storm.tuple.Values;  
  27.   
  28. /** 
  29.  * 本地运行: 
  30.  *   实现累加 
  31.  * @author zm 
  32.  * 
  33.  */  
  34. public class MyLocalStormTopology {  
  35.   
  36.     /** 
  37.      * 组装火车 轨道  并让火车在轨道上行驶 
  38.      * @throws InterruptedException  
  39.      */  
  40.     public static void main(String[] args) throws Exception {  
  41.   
  42.         // 祖品列车  
  43.         TopologyBuilder topologyBuilder = new TopologyBuilder();  
  44.         topologyBuilder.setSpout("1"new MySpout2()); // 定义1号车厢  
  45.         topologyBuilder.setBolt("2"new MyBolt1()).shuffleGrouping("1");// 定义2号车厢 并和1号车厢连接起来     
  46.         // 造出轨道  
  47.         /*LocalCluster localCluster = new LocalCluster();// 造出轨道 在本地运行 
  48.         Config config = new Config();    
  49.         // 轨道上运行列车, 三个参数分别为:定义的列车名,列车服务人员,轨道上跑的列车本身 
  50.         localCluster.submitTopology(MyLocalStormTopology.class.getSimpleName(), config, topologyBuilder.createTopology()); 
  51.          
  52.         TimeUnit.SECONDS.sleep(99999);// 设置列车运行时间 
  53.         localCluster.shutdown();// 跑完后就停止下来, 否则storm是永不停止 
  54. */        
  55.         // 造出轨道 在集群中运行  
  56.         StormSubmitter stormSubmitter = new StormSubmitter();// storm集群执行  
  57.         HashMap conf = new HashMap();  
  58.         stormSubmitter.submitTopology(MyLocalStormTopology.class.getSimpleName(), conf, topologyBuilder.createTopology());  
  59.           
  60.     }  
  61.   
  62. }  
  63.   
  64. //创建火车头  
  65. class MySpout2 extends BaseRichSpout {  
  66.   
  67.     private Map conf;  
  68.     private TopologyContext context;  
  69.     private SpoutOutputCollector collector;  
  70.       
  71.     // 此方法首先被调用  打开storm系统外的数据源  
  72.     public void open(Map conf, TopologyContext context, SpoutOutputCollector collector) {  
  73.         this.conf = conf;  
  74.         this.context = context;  
  75.         this.collector = collector;  
  76.     }  
  77.   
  78.     private int i = 0;  
  79.     // 认为是NameNode的heartbeat,永无休息的死循环的调用 并是线程安全的操作, 这里每一次调用此方法 将i++发送到bolt  
  80.     public void nextTuple() {  
  81.         System.err.println(i);  
  82.         // 将数据(i++)放在弹壳(Values)中,并发送给bolt  
  83.         this.collector.emit(new Values(i++));  
  84.         try {  
  85.             List linesNum = FileUtils.readLines(new File("D:/father"));  
  86.             System.err.println("文件行数为: " + linesNum.size());  
  87.         } catch (IOException e1) {  
  88.             System.err.println("文件行数为: 0 读取失败" );  
  89.             // TODO Auto-generated catch block  
  90.             e1.printStackTrace();  
  91.         }  
  92.         try {  
  93.             TimeUnit.SECONDS.sleep(1);  
  94.         } catch (InterruptedException e) {  
  95.             e.printStackTrace();  
  96.         }  
  97.     }  
  98.   
  99.     //声明输出的字段的名称为 v1   只有在输出给别人时才会重写此方法  
  100.     public void declareOutputFields(OutputFieldsDeclarer declarer) {  
  101.         declarer.declare(new Fields("v1"));  
  102.     }  
  103.       
  104. }  
  105.   
  106. // 创建车厢  
  107. class MyBolt1 extends BaseRichBolt{  
  108.   
  109.     private Map stormConf;  
  110.     private TopologyContext context;  
  111.     private OutputCollector collector;  
  112.       
  113.     // 准备下要对接收storm spout发送来的数据  
  114.     public void prepare(Map stormConf, TopologyContext context,OutputCollector collector) {  
  115.         this.stormConf = stormConf;  
  116.         this.context = context;  
  117.         this.collector = collector;  
  118.     }  
  119.   
  120.     private int sum = 0;  
  121.     // 死循环,用于接收bolt送来的数据   这里storm每调用一次此方法 则获取发送来的tuple数据  
  122.     public void execute(Tuple input) {  
  123.         int i = input.getIntegerByField("v1");  
  124.         sum += i;  
  125.         System.err.println(sum);  
  126.     }  
  127.   
  128.     // 只有向外发送数据时 此方法才会被调用 否则 不要实现此方法   
  129.     public void declareOutputFields(OutputFieldsDeclarer declarer) {  
  130.           
  131.     }  
  132.       
  133. }  

 

 
3.1) 将代码通过eclipse export 导出包为: stormApp.jar, 上传到storm集群中,执行命令如下:
Java代码  收藏代码
  1. [root@h2master local]# storm/bin/storm jar stormApp.jar changping.houzhihoujue.storm.MyLocalStormTopology  
  2.   
  3. 可以看到提交成功:  
  4. Successfully uploaded topology jar to assigned location: /usr/local/storm/tmp/nimbus/inbox/stormjar-ffe04877-a31b-426e-bc21-02f201e8cdc2.jar  
  5.   
  6.    
 
4 在UI上可以看到提交的 累加Topology summary 任务如下:


 
 
停止此任务命令写法为:  kill 后面的名称为 上面截图中 红圈的名称
 这样就关闭了累加的storm任务
 
Java代码  收藏代码
  1. # storm/bin/storm kill MyLocalStormTopology