Storm介绍

Storm超实用教程详解-附示例 Storm 中最重要的抽象,应该就是 Stream grouping 了,它能够控制 Spot/Bolt 对应的 Task 以什么样的方式来分发 Tuple,将 Tuple 发射到目的 Spot/Bolt 对应的 Task.定义拓扑的时候,一部分工作是指定每个Bolt应该消费哪些流。是一个轻量级的数据格式,支持基本的类型,如果想实现自定义的类型,需要实现自己的序列化方式。把数据的计算处理过程合理的拆分到多个Bolt、合理设置Bolt的task数量,能够提高Bolt的处理能力,提升流水线的并发度。 阅读详情

Storm介绍

Storm是Twitter开源的分布式实时大数据处理框架,最早开源于github,从0.9.1版本之后,归于Apache社区,被业界称为实时版Hadoop。随着越来越多的场景对Hadoop的MapReduce高延迟无法容忍,比如网站统计、推荐系统、预警系统、金融系统(高频交易、股票)等等,大数据实时处理解决方案(流计算)的应用日趋广泛,目前已是分布式技术领域最新爆发点,而Storm更是流计算技术中的佼佼者和主流。

Storm的核心组件

  • Nimbus:即Storm的Master,负责资源分配和任务调度。一个Storm集群只有一个Nimbus。
  • Supervisor:即Storm的Slave,负责接收Nimbus分配的任务,管理所有Worker,一个Supervisor节点中包含多个Worker进程。
  • Worker:工作进程,每个工作进程中都有多个Task。
  • Task:任务,在 Storm 集群中每个 Spout 和 Bolt 都由若干个任务(tasks)来执行。每个任务都与一个执行线程相对应。
  • Topology:计算拓扑,Storm 的拓扑是对实时计算应用逻辑的封装,它的作用与 MapReduce 的任务(Job)很相似,区别在于 MapReduce 的一个 Job 在得到结果之后总会结束,而拓扑会一直在集群中运行,直到你手动去终止它。拓扑还可以理解成由一系列通过数据流(Stream Grouping)相互关联的 Spout 和 Bolt 组成的的拓扑结构。
  • Stream:数据流(Streams)是 Storm 中最核心的抽象概念。一个数据流指的是在分布式环境中并行创建、处理的一组元组(tuple)的无界序列。数据流可以由一种能够表述数据流中元组的域(fields)的模式来定义。
  • Spout:数据源(Spout)是拓扑中数据流的来源。一般 Spout 会从一个外部的数据源读取元组然后将他们发送到拓扑中。根据需求的不同,Spout 既可以定义为可靠的数据源,也可以定义为不可靠的数据源。一个可靠的 Spout能够在它发送的元组处理失败时重新发送该元组,以确保所有的元组都能得到正确的处理;相对应的,不可靠的 Spout 就不会在元组发送之后对元组进行任何其他的处理。一个 Spout可以发送多个数据流。
  • Bolt:拓扑中所有的数据处理均是由 Bolt 完成的。通过数据过滤(filtering)、函数处理(functions)、聚合(aggregations)、联结(joins)、数据库交互等功能,Bolt 几乎能够完成任何一种数据处理需求。一个 Bolt 可以实现简单的数据流转换,而更复杂的数据流变换通常需要使用多个 Bolt 并通过多个步骤完成。
  • Stream grouping:为拓扑中的每个 Bolt 的确定输入数据流是定义一个拓扑的重要环节。数据流分组定义了在 Bolt 的不同任务(tasks)中划分数据流的方式。在 Storm 中有八种内置的数据流分组方式。
  • Reliability:可靠性。Storm 可以通过拓扑来确保每个发送的元组都能得到正确处理。通过跟踪由 Spout 发出的每个元组构成的元组树可以确定元组是否已经完成处理。每个拓扑都有一个“消息延时”参数,如果 Storm 在延时时间内没有检测到元组是否处理完成,就会将该元组标记为处理失败,并会在稍后重新发送该元组。

Storm程序再Storm集群中运行的示例图如下:

Topology

为什么把Topology单独提出来呢,因为Topology是我们开发程序主要的用的组件。
Topology和MapReduce很相像。
MapReduce是Map进行获取数据,Reduce进行处理数据。
而Topology则是使用Spout获取数据,Bolt来进行计算。
总的来说就是一个Topology由一个或者多个的Spout和Bolt组成。

具体流程是怎么走,可以通过查看下面这张图来进行了解。
示例图:

注:图片来源http://www.tianshouzhi.com/api/tutorials/storm/52。

图片有三种模式,解释如下:
第一种比较简单,就是由一个Spout获取数据,然后交给一个Bolt进行处理;
第二种稍微复杂点,由一个Spout获取数据,然后交给一个Bolt进行处理一部分,然后在交给下一个Bolt进行处理其他部分。
第三种则比较复杂,一个Spout可以同时发送数据到多个Bolt,而一个Bolt也可以接受多个Spout或多个Bolt,最终形成多个数据流。但是这种数据流必须是有方向的,有起点和终点,不然会造成死循环,数据永远也处理不完。就是Spout发给Bolt1,Bolt1发给Bolt2,Bolt2又发给了Bolt1,最终形成了一个环状。

Storm 集群安装

之前已经写过了,这里就不在说明了。
博客地址:http://www.panchengming.com/2018/01/26/pancm70/

Storm Hello World

前面讲了一些Storm概念,可能在理解上不太清楚,那么这里我们就用一个Hello World代码示例来体验下Storm运作的流程吧。

环境准备

在进行代码开发之前,首先得做好相关的准备。
本项目是使用Maven构建的,使用Storm的版本为1.1.1。
Maven的相关依赖如下:

  <!--storm相关jar  -->
  <dependency>
    <groupId>org.apache.storm</groupId>
    <artifactId>storm-core</artifactId>
    <version>1.1.1</version>
    <scope>provided</scope>
 </dependency> 

具体流程

在写代码的时候,我们先来明确要用Storm做什么。
那么第一个程序,就简单的输出下信息。
具体步骤如下:

  1. 启动topology,设置好Spout和Bolt。
  2. 将Spout获取的数据传递给Bolt。
  3. Bolt接受Spout的数据进行打印。

Spout

那么首先开始编写Spout类。一般是实现 IRichSpout 或继承BaseRichSpout该类,然后实现该方法。
这里我们继承BaseRichSpout这个类,该类需要实现这几个主要的方法:

一、open

open()方法中是在ISpout接口中定义,在Spout组件初始化时被调用。
有三个参数,它们的作用分别是:

  1. Storm配置的Map;
  2. topology中组件的信息;
  3. 发射tuple的方法;

代码示例:

  @Override
    public void open(Map map, TopologyContext arg1, SpoutOutputCollector collector) {
        System.out.println("open:"+map.get("test"));
        this.collector = collector;
    }

二、nextTuple

nextTuple()方法是Spout实现的核心。
也就是主要执行方法,用于输出信息,通过collector.emit方法发射。

这里我们的数据信息已经写死了,所以这里我们就直接将数据进行发送。
这里设置只发送两次。
代码示例:

     @Override
    public void nextTuple() {
        if(count<=2){
            System.out.println("第"+count+"次开始发送数据...");
            this.collector.emit(new Values(message));
        }
        count++;
    }

三、declareOutputFields

declareOutputFields是在IComponent接口中定义,用于声明数据格式。
即输出的一个Tuple中,包含几个字段。

因为这里我们只发射一个,所以就指定一个。如果是多个,则用逗号隔开。
代码示例:

    @Override
    public void declareOutputFields(OutputFieldsDeclarer declarer) {
        System.out.println("定义格式...");
        declarer.declare(new Fields(field));
    }

四、ack

ack是在ISpout接口中定义,用于表示Tuple处理成功。

代码示例:

    @Override
    public void ack(Object obj) {
        System.out.println("ack:"+obj);
    }

五、fail

fail是在ISpout接口中定义,用于表示Tuple处理失败。

代码示例:

    @Override
    public void fail(Object obj) {
        System.out.println("失败:"+obj);
    }

六、close

close是在ISpout接口中定义,用于表示Topology停止。

代码示例:

  @Override
    public void close() {
        System.out.println("关闭...");
    }

至于还有其他的,这里就不在一一列举了。

Bolt

Bolt是用于处理数据的组件,主要是由execute方法来进行实现。一般来说需要实现 IRichBolt 或继承BaseRichBolt该类,然后实现其方法。
需要实现方法如下:

一、prepare

在Bolt启动前执行,提供Bolt启动环境配置的入口。
参数基本和Sqout一样。
一般对于不可序列化的对象进行实例化。
这里的我们就简单的打印下

    @Override
    public void prepare(Map map, TopologyContext arg1, OutputCollector collector) {
        System.out.println("prepare:"+map.get("test"));
        this.collector=collector;
    }

注:如果是可以序列化的对象,那么最好是使用构造函数。

二、execute

execute()方法是Bolt实现的核心。
也就是执行方法,每次Bolt从流接收一个订阅的tuple,都会调用这个方法。
从tuple中获取消息可以使用 tuple.getString()和tuple.getStringByField();这两个方法。个人推荐第二种,可以通过field来指定接收的消息。
注:如果继承的是IRichBolt,则需要手动ack。这里就不用了,BaseRichBolt会自动帮我们应答。
代码示例:

    @Override
    public void execute(Tuple tuple) {
//      String msg=tuple.getString(0);
        String msg=tuple.getStringByField("test");
        //这里我们就不做消息的处理,只打印
        System.out.println("Bolt第"+count+"接受的消息:"+msg); 
        count++;
        /**
         * 
         * 没次调用处理一个输入的tuple,所有的tuple都必须在一定时间内应答。
         * 可以是ack或者fail。否则,spout就会重发tuple。
         */
//      collector.ack(tuple);
    }

三、declareOutputFields

和Spout的一样。
因为到了这里就不再输出了,所以就什么都没写。

    @Override
    public void declareOutputFields(OutputFieldsDeclarer arg0) {        
    }

cleanup

cleanup是IBolt接口中定义,用于释放bolt占用的资源。
Storm在终止一个bolt之前会调用这个方法。
因为这里没有什么资源需要释放,所以就简单的打印一句就行了。

@Override
    public void cleanup() {
        System.out.println("资源释放");
    }

Topology

这里我们就是用main方法进行提交topology。
不过在提交topology之前,需要进行相应的设置。
这里我就不一一细说了,代码的注释已经很详细了。
代码示例:

    import org.apache.storm.Config;
    import org.apache.storm.LocalCluster;
    import org.apache.storm.StormSubmitter;
    import org.apache.storm.topology.TopologyBuilder;
    
    /**
     * 
    * Title: App
    * Description:
    * storm测试 
    * Version:1.0.0  
    * @author pancm
    * @date 2018年3月6日
     */
    public class App {
        
        private static final String str1="test1"; 
        private static final String str2="test2"; 
    
        public static void main(String[] args)  {
            // TODO Auto-generated method stub
            //定义一个拓扑
            TopologyBuilder builder=new TopologyBuilder();
            //设置一个Executeor(线程),默认一个
            builder.setSpout(str1, new TestSpout());
            //设置一个Executeor(线程),和一个task
            builder.setBolt(str2, new TestBolt(),1).setNumTasks(1).shuffleGrouping(str1);
            Config conf = new Config();
            conf.put("test", "test");
            try{
              //运行拓扑
           if(args !=null&&args.length>0){ //有参数时,表示向集群提交作业,并把第一个参数当做topology名称
             System.out.println("远程模式");
                 StormSubmitter.submitTopology(args[0], conf, builder.createTopology());
          } else{//没有参数时,本地提交
        //启动本地模式
         System.out.println("本地模式");
        LocalCluster cluster = new LocalCluster();
        cluster.submitTopology("111" ,conf,  builder.createTopology() );
        Thread.sleep(10000);
    //  关闭本地集群
        cluster.shutdown();
          }
            }catch (Exception e){
                e.printStackTrace();
            }   
        }
    }

运行该方法,输出结果如下:

本地模式
定义格式...
open:test
第1次开始发送数据...
第2次开始发送数据...
prepare:test
Bolt第1接受的消息:这是个测试消息!
Bolt第2接受的消息:这是个测试消息!
资源释放
关闭...
 

到这里,是不是基本上对Storm的运作有些了解了呢。
这个demo达到了上述的三种模式图中的第一种,一个Spout传输数据, 一个Bolt处理数据。

那么如果我们想达到第二种模式呢,那又该如何做呢?
假如我们想统计下在一段文本中的单词出现频率的话,我们只需执行一下步骤就可以了。
1.首先将Spout中的message消息进行更改为数组,并依次将消息发送到TestBolt。
2.然后TestBolt将获取的数据进行分割,将分割的数据发送到TestBolt2。
3.TestBolt2对数据进行统计,在程序关闭的时候进行打印。
4.Topology成功配置并且启动之后,等待20秒左右,关闭程序,然后得到输出的结果。

代码示例如下:

Spout
用于发送消息。

    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;
    
    /**
     * 
    * Title: TestSpout
    * Description:
    * 发送信息
    * Version:1.0.0  
    * @author pancm
    * @date 2018年3月6日
     */
    public class TestSpout extends BaseRichSpout{
    
        private static final long serialVersionUID = 225243592780939490L;
    
        private SpoutOutputCollector collector;
        private static final String field="word";
        private int count=1;
        private String[] message =  {
    "My nickname is xuwujing",
    "My blog address is http://www.panchengming.com/",
    "My interest is playing games"
    };
        
        /**
     * open()方法中是在ISpout接口中定义,在Spout组件初始化时被调用。
     * 有三个参数:
     * 1.Storm配置的Map;
     * 2.topology中组件的信息;
     * 3.发射tuple的方法;
     */
        @Override
        public void open(Map map, TopologyContext arg1, SpoutOutputCollector collector) {
            System.out.println("open:"+map.get("test"));
            this.collector = collector;
        }
    
    /**
     * nextTuple()方法是Spout实现的核心。
     * 也就是主要执行方法,用于输出信息,通过collector.emit方法发射。
     */
        @Override
        public void nextTuple() {
                
            if(count<=message.length){
                System.out.println("第"+count +"次开始发送数据...");
                this.collector.emit(new Values(message[count-1]));
            }
            count++;
        }
    
    
        /**
     * declareOutputFields是在IComponent接口中定义,用于声明数据格式。
     * 即输出的一个Tuple中,包含几个字段。
     */
        @Override
        public void declareOutputFields(OutputFieldsDeclarer declarer) {
            System.out.println("定义格式...");
            declarer.declare(new Fields(field));
        }
    
        /**
         * 当一个Tuple处理成功时,会调用这个方法
         */
        @Override
        public void ack(Object obj) {
            System.out.println("ack:"+obj);
        }
        
        /**
         * 当Topology停止时,会调用这个方法
         */
        @Override
        public void close() {
            System.out.println("关闭...");
        }
        
        /**
         * 当一个Tuple处理失败时,会调用这个方法
         */
        @Override
        public void fail(Object obj) {
            System.out.println("失败:"+obj);
        }
        
    }

TestBolt

用于分割单词。

    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;
    
    
    /**
     * 
    * Title: TestBolt
    * Description: 
    * 对单词进行分割
    * Version:1.0.0  
    * @author pancm
    * @date 2018年3月16日
     */
    public class TestBolt extends BaseRichBolt{
    
        /**
         * 
         */
        private static final long serialVersionUID = 4743224635827696343L;
        
        private OutputCollector collector;
       
        /**
    * 在Bolt启动前执行,提供Bolt启动环境配置的入口
    * 一般对于不可序列化的对象进行实例化。
    * 注:如果是可以序列化的对象,那么最好是使用构造函数。
    */
        @Override
        public void prepare(Map map, TopologyContext arg1, OutputCollector collector) {
            System.out.println("prepare:"+map.get("test"));
            this.collector=collector;
        }
      
        /**
         * execute()方法是Bolt实现的核心。
         * 也就是执行方法,每次Bolt从流接收一个订阅的tuple,都会调用这个方法。
         */
        @Override
        public void execute(Tuple tuple) {
            String msg=tuple.getStringByField("word");
        System.out.println("开始分割单词:"+msg);
    String[] words = msg.toLowerCase().split(" ");
    for (String word : words) {
    this.collector.emit(new Values(word));//向下一个bolt发射数据
    } 
        
        }
    
        /**
         * 声明数据格式
         */
        @Override
        public void declareOutputFields(OutputFieldsDeclarer declarer) {
            declarer.declare(new Fields("count"));
        }
        
        /**
     * cleanup是IBolt接口中定义,用于释放bolt占用的资源。
     * Storm在终止一个bolt之前会调用这个方法。
         */
        @Override
        public void cleanup() {
            System.out.println("TestBolt的资源释放");
        }
    }
    

Test2Bolt
用于统计单词出现次数。

  
    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;
    
    /**
     * 
    * Title: Test2Bolt
    * Description:
    * 统计单词出现的次数 
    * Version:1.0.0  
    * @author pancm
    * @date 2018年3月16日
     */
    public class Test2Bolt extends BaseRichBolt{
    
        /**
         * 
         */
        private static final long serialVersionUID = 4743224635827696343L;
        
        
        /**
         * 保存单词和对应的计数
         */
        private HashMap<String, Integer> counts = null;
         
        private long count=1;
        /**
    * 在Bolt启动前执行,提供Bolt启动环境配置的入口
    * 一般对于不可序列化的对象进行实例化。
    * 注:如果是可以序列化的对象,那么最好是使用构造函数。
    */
        @Override
        public void prepare(Map map, TopologyContext arg1, OutputCollector collector) {
            System.out.println("prepare:"+map.get("test"));
            this.counts=new HashMap<String, Integer>();
        }
      
        /**
         * execute()方法是Bolt实现的核心。
         * 也就是执行方法,每次Bolt从流接收一个订阅的tuple,都会调用这个方法。
         * 
         */
        @Override
        public void execute(Tuple tuple) {
            String msg=tuple.getStringByField("count");
            System.out.println("第"+count+"次统计单词出现的次数");
            /**
             * 如果不包含该单词,说明在该map是第一次出现
             * 否则进行加1
             */
            if (!counts.containsKey(msg)) {
                counts.put(msg, 1);
            } else {
                counts.put(msg, counts.get(msg)+1);
            }
            count++;
        }
    
        
        /**
     * cleanup是IBolt接口中定义,用于释放bolt占用的资源。
     * Storm在终止一个bolt之前会调用这个方法。
         */
        @Override
        public void cleanup() {
            System.out.println("===========开始显示单词数量============");
            for (Map.Entry<String, Integer> entry : counts.entrySet()) {
                System.out.println(entry.getKey() + ": " + entry.getValue());
            }
            System.out.println("===========结束============");
           System.out.println("Test2Bolt的资源释放");
        }
        
        /**
         * 声明数据格式
         */
        @Override
        public void declareOutputFields(OutputFieldsDeclarer arg0) {
            
        }
    }
    

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;
    
    /**
     * 
    * Title: App
    * Description:
    * storm测试 
    * Version:1.0.0  
    * @author pancm
    * @date 2018年3月6日
     */
    public class App {
        
        private static final String test_spout="test_spout"; 
        private static final String test_bolt="test_bolt"; 
        private static final String test2_bolt="test2_bolt"; 
    
        public static void main(String[] args)  {
            //定义一个拓扑
            TopologyBuilder builder=new TopologyBuilder();
            //设置一个Executeor(线程),默认一个
            builder.setSpout(test_spout, new TestSpout(),1);
            //shuffleGrouping:表示是随机分组
            //设置一个Executeor(线程),和一个task
            builder.setBolt(test_bolt, new TestBolt(),1).setNumTasks(1).shuffleGrouping(test_spout);
            //fieldsGrouping:表示是按字段分组
            //设置一个Executeor(线程),和一个task
            builder.setBolt(test2_bolt, new Test2Bolt(),1).setNumTasks(1).fieldsGrouping(test_bolt, new Fields("count"));
            Config conf = new Config();
            conf.put("test", "test");
            try{
              //运行拓扑
           if(args !=null&&args.length>0){ //有参数时,表示向集群提交作业,并把第一个参数当做topology名称
             System.out.println("运行远程模式");
                 StormSubmitter.submitTopology(args[0], conf, builder.createTopology());
          } else{//没有参数时,本地提交
        //启动本地模式
            System.out.println("运行本地模式");
        LocalCluster cluster = new LocalCluster();
        cluster.submitTopology("Word-counts" ,conf,  builder.createTopology() );
        Thread.sleep(20000);
    //  //关闭本地集群
        cluster.shutdown();
          }
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }

输出结果:

运行本地模式
定义格式...
open:test
第1次开始发送数据...
第2次开始发送数据...
第3次开始发送数据...
prepare:test
prepare:test
开始分割单词:My nickname is xuwujing
开始分割单词:My blog address is http://www.panchengming.com/
开始分割单词:My interest is playing games
第1次统计单词出现的次数
第2次统计单词出现的次数
第3次统计单词出现的次数
第4次统计单词出现的次数
第5次统计单词出现的次数
第6次统计单词出现的次数
第7次统计单词出现的次数
第8次统计单词出现的次数
第9次统计单词出现的次数
第10次统计单词出现的次数
第11次统计单词出现的次数
第12次统计单词出现的次数
第13次统计单词出现的次数
第14次统计单词出现的次数
===========开始显示单词数量============
address: 1
interest: 1
nickname: 1
games: 1
is: 3
xuwujing: 1
playing: 1
my: 3
blog: 1
http://www.panchengming.com/: 1
===========结束============
Test2Bolt的资源释放
TestBolt的资源释放
关闭...

上述的是本地模式运行,如果想在Storm集群中进行使用,只需要将程序打包为jar,然后将程序上传到storm集群中,
输入:

storm jar xxx.jar xxx xxx
说明:第一个xxx是storm程序打包的包名,第二个xxx是运行主程序的路径,第三个xxx则表示主程序输入的参数,这个可以随意。

如果是使用maven打包的话,则需要在pom.xml加上

<plugin>
          <artifactId>maven-assembly-plugin</artifactId>
          <configuration>
            <descriptorRefs>
              <descriptorRef>jar-with-dependencies</descriptorRef>
            </descriptorRefs>
            <archive>
              <manifest>
                <mainClass>com.pancm.storm.App</mainClass>
              </manifest>
            </archive>
          </configuration>
      </plugin>

成功运行程序之后,可以在Storm集群的UI界面查看该程序的状态。

到此,本文结束,谢谢阅读!

如果你对生活感觉到了绝望,请不要气馁。因为这样只会让你更加绝望! 所谓的希望往往都是在绝望中萌发的,所以,请不要放弃希望!

分类: java,storm

标签: storm, demo

好文要顶 关注我 收藏该文  

虚无境
关注 - 29
粉丝 - 204

+加关注

9

0

« 上一篇:Linux CentOS 安装MySql以及搭建MySql主从复制
» 下一篇:Java基础知识回顾之一 ----- 基本数据类型

【Storm】UI介绍 众所周知,storm 已经是业界主流的流时处理框架,Storm 被广泛应用于实时分析,在线机器学习,持续计算、分布式远程调用等领域。当前无论是内部还是外部论坛介绍原理的文档都比较多,但主要都是从运行机制和原理方面的介绍,在 UI 方面的介绍甚少,今天我试着向大家介绍一下 storm ui,一方面可以让大家了解一下 storm 的机制,另外也可以让大家更好的使用好 storm ui 协助大家自助解决... 阅读详情

相关推荐

Vim 入门到够用:Linux 文本编辑器的三种模式、常用操作与实战技巧

i 进入编辑模式Esc 退出编辑模式回到命令模式: 从命令模式进入底行模式编辑,不一定非得“打开就直接打字”。一旦你接受了“模式”这件事,后面很多操作都会顺起来。学 Vim,不要追求一次学全,先把“命令模式—编辑模式—底行模式”这条主线练熟。只要这条主线通了,后面的复制、删除、搜索、替换,都是顺手补上去的能力。

Web安全工具库 802

Storm 入门的Demo教程

Storm介绍 Storm是Twitter开源的分布式实时大数据处理框架,最早开源于github,从0.9.1版本之后,归于Apache社区,被业界称为实时版Hadoop。随着越来越多的场景对Hadoop的MapReduce高延迟无法容忍,比如网站统计、推荐系统、预警系统、金融系统(高频交易、股票)等等,大数据实时处理解决方案(流计算)的应用日趋广泛,目前已是分布式技术领域最新爆发点,而Storm...

weixin_34116110的博客 3503

使用amp训练出现Detected call of lr_scheduler.step() before optimizer.step().

这个警告是怎么产生的?是由于在算梯度的时候出现了nan,所以这一次更新会跳过,但是参数仍旧会更新所以出现了问题,按下面的做法加一个判断就行了。但是在使用amp进行混合精度训练出现的一个warning,调换代码顺序也不work。正常在训练的时候,对于优化器和参数更新的顺序这样就可以了。

weixin_46214675的博客 1306

Storm 流式计算框架介绍

Storm流式计算框架介绍

weixin_44911248的博客 4708

OFDM接收机同步——分组检测

上一篇讲了OFDM发射机中的长短训练序列生成原理,基于此可以得到长短训练序列的准确数值,为接收机中的符号同步中的相关运算提供基础。 进入符号同步前,首先来看OFDM接收机中的第一步——分组检测。分组检测就是检测突发传输方式的信道上是否有新的数据到达,算法的好坏直接影响着接收机的后续工作性能。 一、本文意义 基于《基于xilinx fpga 的ofdm的通信系统基带设计》这本教材中分组检测算法原理,通过matlab编程仿真验证“延时相关+保持长度”分组检测算法的有效性。同时,通过仿真证明教材上的判决公式的问题

boayel的博客 2202

1553B通信项目开发笔记(一)协议概述

最近接了个项目,需要用1553B协议通信,仅作为RT端口进行通信,控制器采用ARM 使用芯片为国产的BU61580芯片,功能和引脚和DDC的61580完全一致。

u010396127的博客 2万+

Storm简单demo

Storm简单demo ​ 上一篇介绍了Storm的基础概念,下面就来实际写个demo。 ​ 因为是开发,所以基础的配置还是没有做,就是说是在本地跑的,没有集群之类的。 ​ 先整合一个基础的架子,使用的是SpringBoot的框架,但是移除了基础依赖,添加了Storm的依赖。上代码 前还是需要先解释一下一些基础的概念。然后再上代码。 ​ Storm中使用tuple来作为数据元,相当于一个一个水滴,很多水滴汇集成流。每个tuple是一堆值,每个值有一个名字,并且每个值可以是任何类型。tuple中有两个概念,V

qq_38533859的博客 501

代码解读:使用Stable Diffusion完成相似图像生成任务

作为内容生产重要的一部分,生成相似图像是一项有意义的工作,例如很多内容创作分享平台单纯依赖用户贡献的图片已经不够了,最省力的方法就是利用已有的图片生成相似的图片作为补充。这篇博客详细解读基于Stable Diffusion生成相似图片的原理和代码。

沉迷单车的追风少年 1394

大数据与云计算:Storm部署配置及运行WordCountTopology (保姆级教程!)

当今世界正处于云计算和大数据的快速发展阶段,而Storm作为一种高效、可靠的实时计算框架,受到了广泛的关注和应用。在这篇文章中,我们将从头开始,将提供一份保姆级教程,帮助进行相关配置和运行WordCountTopology。向您展示如何配置Storm环境。我们将详细介绍所需的软件和工具,并提供逐步指导,帮助您完成安装和配置过程。本人也在不断努力进步,希望自己的博文能够希望对各位有所帮助。

专注 AI、大数据、Python、爬虫、数据分析可视化、机器学习、推荐算法、知识图谱、大模型应用与全栈系统开发,长期沉淀真实项目案例、源码解析、系统设计、部署经验与工程化实践,分享可运行、可复用、可落地的技术方案。 2472

OpenClaw插件开发指南:扩展AI智能体的无限可能

OpenClaw插件开发指南介绍了如何扩展AI智能体的功能。该插件系统支持多种类型(功能、集成、工具、界面、工作流插件),具有模块化、低耦合等优势。开发环境需要安装SDK和工具包,通过plugin.json配置插件信息,主文件实现核心功能。API提供智能体管理、任务执行等接口,示例演示了文本处理插件的创建流程。开发者可基于此框架灵活扩展OpenClaw的能力。

一键难忘的博客 561

Autosar代码包初识 2 - 如何编译Vector包内Demo工程

Vetcor autosar代码包Demo工程编译,GreenHills,RH850,Autosar,Davinci COnfigurator

weixin_42412049的博客 5186

storm 介绍

storm本Markdown编辑器使用StackEdit修改而来,用它写博客,将会带来全新的体验哦: Markdown和扩展Markdown简洁的语法 代码块高亮 图片链接和图片上传 LaTex数学公式 UML序列图和流程图 离线写博客 导入导出Markdown文件 丰富的快捷键 https://my.oschina.net/zhangglin/blog/352032 加粗 Ctrl + B

yanhx1204的专栏 449

YOLOv12改进前必看 - YAML模型配置文件详细解读(再也不用担心通道数不匹配) 附网络结构图

YOLOv12的模型配置文件在中,里面包含yolov12的以及的不同大小的模型,本文将详细介绍一下YOLOv12模型文件中各参数的含义。

Limiiiing的博客 3278

storm原理介绍

storm原理介绍@(STORM)[storm, 大数据]storm原理介绍 一原理介绍Why use Storm 1适用场景 2集群相关概念 3拓扑相关概念 二配置 三并行度 一storm拓扑的并行度可以从以下4个维度进行设置 二并行度的设置方法 三示例 四分组 五可靠性 一spout 二bolt 一、原理介绍Why use Storm?**Apache Storm is a free and o

jediael_lu的专栏 1523

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

Storm介绍及demo

Storm介绍 Storm是Twitter开源的分布式实时大数据处理框架,最早开源于github,从0.9.1版本之后,归于Apache社区,被业界称为实时版Hadoop。随着越来越多的场景对Hadoop的MapReduce高延迟无法容忍,比如网站统计、推荐系统、预警系统、金融系统(高频交易、股票)等等,大数据实时处理解决方案(流计算)的应用日趋广泛,目前已是分布式技术领域最新爆发点,而Storm更是流计算技术中的佼佼者和主流。 Storm的核心组件 Nimbus:即Storm的Master,负责资源分配和

qq_39583810的博客 342

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

Storm安装介绍

将安装过storm 0.9.1的过程流水记录,稍微整理了一下,以备日后查看。 0. introduction 配置项说明: storm在conf/storm.yaml包含了一些配置信息。 storm.zookeeper.servers/port:配置storm集群使用的zookeeper集群的地址/端口 storm.local.dir:Nimbus和Supervisor在本地磁盘上

BIT工匠 2965

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

storm介绍

Storm介绍 Storm是Twitter开源的分布式实时大数据处理框架,最早开源于github,从0.9.1版本之后,归于Apache社区,被业界称为实时版Hadoop。随着越来越多的场景对Hadoop的MapReduce高延迟无法容忍,比如网站统计、推荐系统、预警系统、金融系统(高频交易、股票)等等,大数据实时处理解决方案(流计算)的应用日趋广泛,目前已是分布式技术领域最新爆发点,而Stor...

SDKLHKJAS的博客 261

Apache Storm入门介绍之三分钟看懂Apache Storm

Apache Storm 入门介绍。Storm 是一个分布式实时大数据处理系统。Storm 旨在以容错和水平可扩展的方法处理大量数据。它是一个流数据框架,具有最高摄取率的能力。虽然 Storm 是无状态的,但它通过 Apache ZooKeeper 管理分布式环境和集群状态。它很简单,您可以对实时数据并行执行各种操作。

日拱一卒无有尽,功不唐捐终入海 5019

Storm介绍及原理

2019独角兽企业重金招聘Python工程师标准>>> ...

weixin_34362790的博客 345

storm部分:storm的架构介绍

storm是并行计算的框架 storm是一种有向无环的方式,并且是并行计算的方式,是一种实时的方式  flume:消息采集器 kafka:消息队列 storm异步实时处理请求: 异步是指是有向无环的方式 同步的话:需要借助于分布式远程服务  Storm的架构: Spolt负责推送数据 Bolt负责处理数据 topology负责分发策略 local cl...

wyqwilliam的博客 1011

STORM介绍及项目分工

(一)strom介绍 Storm 是一个免费开源的分布式实时计算系统。简化了流数据的可靠处理,像 Hadoop 一样实现实时批处理。Storm 很简单,可用于任意编程语言。Apache Storm 采用Clojure开发。目前的最新版本是Apache Storm2.3.0 Storm 有很多应用场景,包括实时数据分析、联机学习、持续计算、分布式 RPC、ETL 等。Storm 速度非常快,一个测试在单节点上实现每秒一百万的组处理。 Storm也是基于C/S架构来进行工作的,C负责将数据处理的方式...

siwujidan_77的博客 552

1 ,storm 框架介绍

1 ,两种大数据框架 : 批处理 : 一批数据一起,走一波 例如 : mr 实时处理 : 不停走,来一个数据,走一波 例如 :storm 2 ,storm 特征 : 快,实时 Storm 是个实时的、分布式以及具备高容错的计算系统 Storm 进程常驻内存 Storm 数据不经过磁盘,在内存中处理 3 ,官网 : http://storm.apache.org/ 4 ,storm 架构 ...

孙砚秋的博客 1087

Storm 介绍

介绍 Storm的简介 Storm是Twitter开源的分布式实时大数据处理框架,被业界称为实时版Hadoop。随着越来越多的场景对Hadoop的MapReduce高延迟无法容忍,比如网站统计、推荐系统、预警系统、金融系统(高频交易、股票)等等,大数据实时处理解决方案(流计算)的应用日趋广泛,目前已是分布式技术领域最新爆发点,而Storm更是流计算技术中的佼佼者和主流。 按照storm作者的说法,Storm对于实时计算的意义类似于Hadoop对于批处理的意义。Hadoop提供了map、reduce原语,使我

XGkerwin1的博客 913
上一篇: OpenTSDB数据写入 - 数据库其他综合
下一篇: 各大公司Java面试题超详细总结
王树民
博客等级 码龄10年 912粉丝 560原创
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值