storm1.2.2集群搭建

1 篇文章 0 订阅
0 篇文章 0 订阅

storm是一个流式并行计算框架,该框架的特点流式处理,尽可能快地处理数据,所以一般被应用在需要实时得出结果的场景。对于一个jar包提交上去的任务对应其内部一整个流程,称为topology,而一个topology里的编程模型有两种组件:

  • spout 负责接收外部数据,下发到blot组件
  • blot 一种是ack的blot,负责处理错误数据,执行重发机制;另一种就是需要我们实现的业务blot,用于接收spout下发的数据,并进行业务处理,处理完毕可以接下一个blot继续处理业务,也可以将数据存储到持久层。

storm框架也有主从节点,主节点成为nimbus,负责唤醒supervisor节点,而从节点称为supervisor,负责提交jar包,并启动设定好的work数量,而一个work就是一个执行任务,负责执行jar包上的程序。

搭建流程

  1. 首先需要有zookeeper集群,并启动集群才能将supervisor节点联系在一起
  2. 配置storm文件,启动storm集群
  3. 编写storm代码,提交jar包到集群上执行

搭建步骤

  1. 下载storm安装包住,这里我使用的是storm-1.2.2版本:
    storm1.2.2

  2. 解压storm安装包

    tail -zxvf apache-storm-1.2.2.tar.gz -C /usr/local
    
  3. 修改storm安装路径

    mv /usr/local/apache-storm-1.2.2  /usr/local/storm
    
  4. 修改storm文件配置

    vi storm.yaml
    
    • storm.yaml配置文件信息如下:
    #指定storm使用的zk集群
    storm.zookeeper.servers:
         - "hadoop1"
         - "hadoop2"
         - "hadoop3"
         - "hadoop4"
    #指定storm本地状态保存地址
    storm.local.dir: "/usr/local/storm/workdir"
    #指定storm集群中的nimbus节点所在的服务器
    nimbus.host: "hadoop1"
    #指定nimbus启动JVM最大可用内存大小
    nimbus.childopts: "-Xmx1024m"
    #指定supervisor启动JVM最大可用内存大小
    supervisor.childopts: "-Xmx1024m"
    #指定supervisor节点上,每个worker启动JVM最大可用内存大小
    worker.childopts: "-Xmx768m"
    #指定ui启动JVM最大可用内存大小,ui服务一般与nimbus同在一个节点上。
    ui.childopts: "-Xmx768m"
    #指定supervisor节点上,启动worker时对应的端口号,每个端口对应槽,每个槽位对应一个worker
    supervisor.slots.ports:
        - 6700
        - 6701
        - 6702
        - 6703
    
    
    配置文件注意要点:
    1. storm.zookeeper.servers 配置需要集群的storm机器主机名或ip
    2. storm.local.dir 尽量配置在storm安装目录中,以便分发都其他机器上
    3. nimbus.host 根据自己需要配置一台机器作为storm的nimbus节点
    4. supervisor.slots.ports 配置多个supervisor启动worker的端口,用来建立supervisor与worker的通讯
  5. 创建一个保存storm的主从节点以及blot组件状态信息的工作目录

    mkdir -p /usr/local/storm/workdir
    
  6. 分发配置好的storm到其他机器上

    scp -r /usr/local/storm hadoop2:/usr/local
    scp -r /usr/local/storm hadoop3:/usr/local
    scp -r /usr/local/storm hadoop4:/usr/local
    
  7. 启动zookeeper集群,如果没有安装zookeeper的,请按照这个步骤搭建zk集群
    zookeeper3.4.13集群搭建

  8. 在配置nimbus节点的机器上启动storm的nimbus节点:

    nohup storm nimbus &
    
    nohup storm ui & //启动storm的管理界面
    
  9. 在其他机器上启动supervisor节点,前提是启动的机器必须是zookeeper集群中的一台:

    nohup storm supervisor &
    
    • 输入网址:hadoop1:8080
    • hadoop1 表示nimbus节点所在机器的主机名
      在这里插入图片描述
    如果出现上图则表示storm搭建成功!!!

storm并发编程

  • storm里面一个流程从接收数据到处理数据这个过程称为一个topology,可以这么理解,当我们自己编写一个java程序打包成一个jar包提交到storm上,那么storm在执行这个jar的过程就是一个topology。

  • 一个topology里面包含了很多个task,这些task的类型大致分两种,一种是spout,另一种是blot,而storm还有内置的ack blot用于处理错误数据,实现重发机制。spout和blot是storm的编程模型,也就是说我们需要在这上面编写自己的业务代码。

    spout 用于接收外部数据,并发射到blot组件上进行处理

    blot 接收spout发射过来的数据,进行业务处理,然后发射到另一个bolt进行处理或存储到持久层

  • 从物理上,storm有两种节点类型,一种是nimbus节点,属于主节点,负责分配任务,监控任务;一种是supervisor节点,属于从节点,接收nimbus分配过来的任务,并启动自己的worker,worker数量是根据端口号来的。而worker是执行具体任务的组件,相当于一个线程,一个worker可以存在多个task

  • 在storm中有并发度的概念,指的是一种类型的task(spout / blot)被几个线程同时执行

实例演示

  • 实现一个可以单词实时统计的功能

    创建一个maven工程,在pom文件中添加如下信息
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
      <modelVersion>4.0.0</modelVersion>
      <groupId>com.guoyu</groupId>
      <artifactId>kafka</artifactId>
      <version>0.0.1-SNAPSHOT</version>
      <name>MyKafka</name>
      
      <properties>
    		<java.version>1.8</java.version>
      </properties>
      
      <dependencies>
      	<dependency>
          <groupId>junit</groupId>
          <artifactId>junit</artifactId>
          <version>3.8.1</version>
          <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.apache.storm</groupId>
            <artifactId>storm-core</artifactId>
            <version>1.2.2</version>
            <scope>provided</scope>
        </dependency>
        
       </dependencies>
       
    	 <build>
         <plugins>
           <plugin>
             <artifactId>maven-assembly-plugin</artifactId>
             <configuration>
               <descriptorRefs>
                 <descriptorRef>jar-with-dependencies</descriptorRef>
               </descriptorRefs>
             </configuration>
             <executions>
               <execution>
                 <id>make-assembly</id> 
                 <phase>package</phase>
                 <goals>
                   <goal>single</goal>
                 </goals>
               </execution>
             </executions>
           </plugin>
           <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <configuration>
                        <source>1.8</source>
                        <target>1.8</target>
                    </configuration>
                </plugin>
         </plugins>
       </build>
    </project>
    
    topology代码演示
    import org.apache.storm.Config;
    import org.apache.storm.LocalCluster;
    import org.apache.storm.StormSubmitter;
    import org.apache.storm.topology.TopologyBuilder;
    import org.apache.storm.tuple.Fields;
    
    import com.guoyu.storm.bolt.SplitBolt;
    import com.guoyu.storm.bolt.WordCountBolt;
    import com.guoyu.storm.spout.WordCountSpout;
    
    public class WordCountTopology {
    	
    	public static void main(String[] args) {
    		TopologyBuilder topology = new TopologyBuilder();
    		topology.setSpout("spout", new WordCountSpout(),1);
    		topology.setBolt("blot1", new SplitBolt(),10).shuffleGrouping("spout");
    		topology.setBolt("blot2", new WordCountBolt(), 2).fieldsGrouping("blot1", new Fields("word"));
    		
    		Config conf = new Config();
    		conf.setNumWorkers(3);
    		
    		//集群模式
    		//StormSubmitter.submitTopology("mywordcount", conf, topology);
    		
    			LocalCluster local = new LocalCluster();
    			local.submitTopology("mywordcount", conf, topology.createTopology());
    			
    	}
    }
    
    
    
    • topology作为一个程序入口,设置相应的spout和blot,设置具体的配置。storm提供了两种模式:一种是集群模式,一种是本地模式。
    spout代码演示
    import java.util.HashMap;
    import java.util.Map;
    
    import org.apache.storm.spout.SpoutOutputCollector;
    import org.apache.storm.task.TopologyContext;
    import org.apache.storm.topology.OutputFieldsDeclarer;
    import org.apache.storm.topology.base.BaseRichSpout;
    import org.apache.storm.tuple.Fields;
    import org.apache.storm.tuple.Values;
    
    public class WordCountSpout extends BaseRichSpout{
    
    SpoutOutputCollector collector;
    Map<String,Integer> map = new HashMap<String,Integer>();
    
    public void open(Map conf, TopologyContext context, SpoutOutputCollector collector) {
    	this.collector = collector;
    }
    
    public void nextTuple() {
    	String str = "I am super man , I am guoyu";
    	collector.emit(new Values(str));
    	
    }
    
    public void declareOutputFields(OutputFieldsDeclarer declarer) 	{
    	declarer.declare(new Fields("god"));
    }
    
    
    清洗数据的bolt代码演示
    import java.util.Map;
    
    import org.apache.storm.task.OutputCollector;
    import org.apache.storm.task.TopologyContext;
    import org.apache.storm.topology.OutputFieldsDeclarer;
    import org.apache.storm.topology.base.BaseRichBolt;
    import org.apache.storm.tuple.Fields;
    import org.apache.storm.tuple.Tuple;
    import org.apache.storm.tuple.Values;
    
    public class SplitBolt extends BaseRichBolt{
    	
    	OutputCollector collector;
    	
    	public void prepare(Map stormConf, TopologyContext context, OutputCollector collector) {
    		this.collector = collector;
    	}
    
    	public void execute(Tuple input) {
    		String str = input.getString(0);
    		String[] words = str.split(" ");
    		for(String word : words) {
    			collector.emit(new Values(word,1));
    		}
    	}
    
    	public void declareOutputFields(OutputFieldsDeclarer declarer) {
    		declarer.declare(new Fields("word","num"));
    	}
    
    }
    
    单词统计的blot
    import java.util.HashMap;
    import java.util.Map;
    
    import org.apache.storm.task.OutputCollector;
    import org.apache.storm.task.TopologyContext;
    import org.apache.storm.topology.OutputFieldsDeclarer;
    import org.apache.storm.topology.base.BaseRichBolt;
    import org.apache.storm.tuple.Tuple;
    
    public class WordCountBolt extends BaseRichBolt{
    	
    	OutputCollector collector;
    	
    	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 count = input.getInteger(1);
    		if(map.containsKey(word)) {
    			map.put(word, map.get(word)+1);
    		}else {
    			map.put(word,count);
    		}
    		System.out.println("count:"+map);
    	}
    
    	public void declareOutputFields(OutputFieldsDeclarer declarer) {
    		
    	}
    
    	
    }
    
    • 这里,我们先使用本地模式测试,效果如图:

    在这里插入图片描述

    • 在我们编写spout这个task上,里面的nextTuple方法是循环调用的,所以输出的数据会循环统计
    集群模式
    • 使用maven,将项目打成jar包

      在这里插入图片描述

    • 生成jar包的效果图

      在这里插入图片描述

    • 将jar包放在nimbus节点的机器上,执行提交命令,就可以启动集群模式了

      storm jar  wordcount-0.0.1-SNAPSHOT-jar-with-dependencies.jar com.guoyu.storm.topology.WordCountTopology wordcount		
      
    • 打开管理页面就可以看到提交上去的jar包

      在这里插入图片描述

    • 点击wordcount打开详情页面,就可以知道worker在哪台机器上执行jar包

      在这里插入图片描述

    • 定位执行jar包的机器,在其机器上查看storm的日志打印

    cd /usr/local/storm/logs/workers-artifacts/wordcount-1-1558526639/6700
    tail -f worker.log
    

    在这里插入图片描述

    • 注:pom文件中storm的jar引用需要添加作用域,集群启动才能生效

      在这里插入图片描述

    单词实时统计次数的storm实例就此告一段落!!!

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值