storm任务提交流程

来源:互联网 发布:淘宝卖家有ipad客户端 编辑:程序博客网 时间:2024/05/17 06:16

原文链接

源码查看的是1.0.3版本的jar

1、Client端提交Topology到nimbus
调用命令:

storm jar WordCount.jar storm.starter.storm.starter wordcount

实际上调用的是:

storm -client WordCount.jar storm.starter.storm.starter wordcount

2、通过TopologyBuilder将Spout和Bolt按照一定的逻辑顺序构建Topology程序

TopologyBuilder builder = new TopologyBuilder();builder.setSpout("spout", new RandomIntegerSpout());builder.setBolt("partialsum", new StatefulSumBolt("partial"), Integer.valueOf(1)).shuffleGrouping("spout");builder.setBolt("printer", new PrinterBolt(), Integer.valueOf(2)).shuffleGrouping("partialsum");builder.setBolt("total", new StatefulSumBolt("total"), Integer.valueOf(1)).shuffleGrouping("printer");

3、通过调用TopologyBuilder的createTopology()方法,获取StormTopology实例对象。源码如下:

// 该方法用于创建Topology对象public StormTopology createTopology() {    ComponentCommon common;    java.util.Map boltSpecs = new HashMap();    java.util.Map spoutSpecs = new HashMap();    maybeAddCheckpointSpout();    for (String boltId : this._bolts.keySet()) {      IRichBolt bolt = (IRichBolt)this._bolts.get(boltId);      bolt = maybeAddCheckpointTupleForwarder(bolt);      common = getComponentCommon(boltId, bolt);      try {        maybeAddCheckpointInputs(common);        boltSpecs.put(boltId, new Bolt(ComponentObject.serialized_java(Utils.javaSerialize(bolt)), common));      } catch (RuntimeException wrapperCause) {        if ((wrapperCause.getCause() != null) && (NotSerializableException.class.equals(wrapperCause.getCause().getClass())))        {          throw new IllegalStateException("Bolt '" + boltId + "' contains a non-serializable field of type " + wrapperCause            .getCause().getMessage() + ", which was instantiated prior to topology creation. " + wrapperCause            .getCause().getMessage() + " should be instantiated within the prepare method of '" + boltId + " at the earliest.", wrapperCause);        }        throw wrapperCause;      }    }    for (String spoutId : this._spouts.keySet()) {      IRichSpout spout = (IRichSpout)this._spouts.get(spoutId);      common = getComponentCommon(spoutId, spout);      try {        spoutSpecs.put(spoutId, new SpoutSpec(ComponentObject.serialized_java(Utils.javaSerialize(spout)), common));      } catch (RuntimeException wrapperCause) {        if ((wrapperCause.getCause() != null) && (NotSerializableException.class.equals(wrapperCause.getCause().getClass())))        {          throw new IllegalStateException("Spout '" + spoutId + "' contains a non-serializable field of type " + wrapperCause            .getCause().getMessage() + ", which was instantiated prior to topology creation. " + wrapperCause            .getCause().getMessage() + " should be instantiated within the prepare method of '" + spoutId + " at the earliest.", wrapperCause);        }        throw wrapperCause;      }    }    // 把Spout和Bolt相关信息存放到map中,并返回Topology对象    StormTopology stormTopology = new StormTopology(spoutSpecs, boltSpecs, new HashMap());    stormTopology.set_worker_hooks(this._workerHooks);    return stormTopology;  }

4、开始提交任务,具体过程如下
(1)调用StormSubmitter.submitTopologyWithProgressBar(args[0], conf, builder.createTopology());提交任务(这种提交方式是集群下的提交)

submitTopologyWithProgressBar方法:public static void submitTopologyWithProgressBar(String name, Map stormConf, StormTopology topology, SubmitOptions opts)    throws AlreadyAliveException, InvalidTopologyException, AuthorizationException  {    // 在此方法中有调用了submitTopology方法    submitTopology(name, stormConf, topology, opts, new ProgressListener()    {      public void onStart(String srcFile, String targetFile, long totalBytes) {        System.out.printf("Start uploading file '%s' to '%s' (%d bytes)\n", new Object[] { srcFile, targetFile, Long.valueOf(totalBytes) });      }      public void onProgress(String srcFile, String targetFile, long bytesUploaded, long totalBytes)      {        int length = 50;        int p = (int)(length * bytesUploaded / totalBytes);        String progress = StringUtils.repeat("=", p);        String todo = StringUtils.repeat(" ", length - p);        System.out.printf("\r[%s%s] %d / %d", new Object[] { progress, todo, Long.valueOf(bytesUploaded), Long.valueOf(totalBytes) });      }      public void onCompleted(String srcFile, String targetFile, long totalBytes)      {        System.out.printf("\nFile '%s' uploaded to '%s' (%d bytes)\n", new Object[] { srcFile, targetFile, Long.valueOf(totalBytes) }); } } );  }

(2) submitTopologyWithProgressBar方法中又调用了StormSubmitter的submitTopologyf方法。
submitTopology方法:

public static void submitTopology(String name, Map stormConf, StormTopology topology, SubmitOptions opts, ProgressListener progressListener)    throws AlreadyAliveException, InvalidTopologyException, AuthorizationException  {    submitTopologyAs(name, stormConf, topology, opts, progressListener, null);  }

(3)而在submitTopology方法又调用了submitTopology的submitTopologyAs方法
submitTopologyAs方法:

public static void submitTopologyAs(String name, Map stormConf, StormTopology topology, SubmitOptions opts, ProgressListener progressListener, String asUser)    throws AlreadyAliveException, InvalidTopologyException, AuthorizationException, IllegalArgumentException  { // 检查Stormconf必须是json-serializable Json序列化对象 if (!(Utils.isValidConf(stormConf)))      throw new IllegalArgumentException("Storm conf is not valid. Must be json-serializable");    stormConf = new HashMap(stormConf);    stormConf.putAll(Utils.readCommandLineOpts());    Map conf = Utils.readStormConfig();    conf.putAll(stormConf);    // 获得命令行参数,并把它放到Stormconf中    stormConf.putAll(prepareZookeeperAuthentication(conf));    validateConfs(conf, topology);    Map passedCreds = new HashMap();    if (opts != null) {      Credentials tmpCreds = opts.get_creds();      if (tmpCreds != null)        passedCreds = tmpCreds.get_creds();    }    Map fullCreds = populateCredentials(conf, passedCreds);    if (!(fullCreds.isEmpty())) {      if (opts == null)        opts = new SubmitOptions(TopologyInitialStatus.ACTIVE);      opts.set_creds(new Credentials(fullCreds));    }    try {      // 判断nimbus是否为空,如果不为空,启动本地运行模式      if (localNimbus != null) {        LOG.info("Submitting topology " + name + " in local mode");        if (opts != null) {          localNimbus.submitTopologyWithOpts(name, stormConf, topology, opts);        }        else          localNimbus.submitTopology(name, stormConf, topology);        LOG.info("Finished submitting topology: " + name);      } else {        String serConf = JSONValue.toJSONString(stormConf);        // 检查Topology的名称在集群上是否存在,如果存在抛出异常        if (topologyNameExists(conf, name, asUser))          throw new RuntimeException("Topology with name `" + name + "` already exists on cluster");        // 调用submitJarAs方法提交jar文件        String jar = submitJarAs(conf, System.getProperty("storm.jar"), progressListener, asUser);        try { NimbusClient client = NimbusClient.getConfiguredClientAs(conf, asUser); Object localObject1 = null;          try { LOG.info("Submitting topology " + name + " in distributed mode with conf " + serConf);            if (opts != null) {              client.getClient().submitTopologyWithOpts(name, jar, serConf, topology, opts);            }            else              client.getClient().submitTopology(name, jar, serConf, topology);            LOG.info("Finished submitting topology: " + name); } catch (Throwable localThrowable2) { } finally {            if (client != null) if (localObject1 != null) try { client.close(); } catch (Throwable localThrowable3) { localObject1.addSuppressed(localThrowable3); } else client.close();            }        } catch (InvalidTopologyException e) {          LOG.warn("Topology submission exception: " + e.get_msg());          throw e;        } catch (AlreadyAliveException e) {          LOG.warn("Topology already alive exception", e);          throw e;        }      }    } catch (TException e) {      throw new RuntimeException(e);    }    invokeSubmitterHook(name, asUser, conf, topology);  }

在submitTopology()方法中,做了一下工作:
1)检验Stormconf,必须是json-serializableJson的序列化对象 Utils.isValidConf(stormConf)

2)判断Topology的运行模式
//STONE_NOTE如果localNimbus不为空的话,调用本地模式运行 localNimbus.submitTopology(name,null,serConf,topology);

3)如果为分布式集群模式运行
//STONE_NOTE检测Topology的名称在集群上是否存在 topologyNameExists(client,conf,name)

//STONE_NOTE调用submitJar方法,提交jar文件
submitJar(client,conf);

//STONE_NOTE新的提交方式,携带opts参数 提交Topology任务
client.getClient().submitTopologyWithOpts(name,path,serConf,topology,opts);
最终任务提交完成!

0 0
原创粉丝点击