2016-05-15 11 views
2

私はKMeansのコードを持っていますが、私の仕事はスピードアップを計算することです、私はuniのクラスタの異なるノード数で実行しました。しかし、マッパーやリデューサーの数を変更することができるので、シングルノードで実行している間にスピードアップの変化を確認することができます。複数のマッパーを1つのノードで実行することは可能ですか?

グーグルでは、私はconf.setNumReduceTasks(2);を使用して、リデューサーの数を変更できることを発見しました。私の出力には何の変化も見られません。 (私の出力はms単位の時間です)。

私が使用しているコードはgithubからです:https://github.com/himank/K-Means/blob/master/src/KMeans.java 私は自分の要件に応じていくつかの変更を加えましたが、主な機能は同じです。

public static void main(String[] args) throws Exception { 
    long startTime = System.currentTimeMillis(); 
    IN = args[0]; 
    OUT = args[1]; 
    String input = IN; 
    String output = OUT + System.nanoTime(); 
    String again_input = output; 
    int iteration = 0; 
    boolean isdone = false; 
    while (isdone == false) { 
     JobConf conf = new JobConf(KMeans.class); 
     if (iteration == 0) { 
      Path hdfsPath = new Path(input + CENTROID_FILE_NAME); 
      DistributedCache.addCacheFile(hdfsPath.toUri(), conf); 
     } else { 
      Path hdfsPath = new Path(again_input + OUTPUT_FILE_NAME); 
      DistributedCache.addCacheFile(hdfsPath.toUri(), conf); 
     } 
     conf.setJobName(JOB_NAME); 
     //conf.setNumReduceTasks(2); 
     conf.setMapOutputKeyClass(DoubleWritable.class); 
     conf.setMapOutputValueClass(DoubleWritable.class); 
     conf.setOutputKeyClass(DoubleWritable.class); 
     conf.setOutputValueClass(Text.class); 
     conf.setMapperClass(Map.class); 
     conf.setNumMapTasks(4); 
     conf.setReducerClass(Reduce.class); 
     conf.setInputFormat(TextInputFormat.class); 
     conf.setOutputFormat(TextOutputFormat.class); 
     FileInputFormat.setInputPaths(conf, new Path(input + DATA_FILE_NAME)); 
     FileOutputFormat.setOutputPath(conf, new Path(output)); 
     JobClient.runJob(conf); 
     Path ofile = new Path(output + OUTPUT_FILE_NAME); 

     Configuration configuration = new Configuration(); 
     FileSystem fs = FileSystem.get(new URI("hdfs://127.0.0.1:9000"), configuration); 
     Path filePath = new Path(output + OUTPUT_FILE_NAME); 
     BufferedReader br = new BufferedReader(new InputStreamReader(fs.open(filePath))); 
     List<Double> centers_next = new ArrayList<Double>(); 
     String line = br.readLine(); 
     while (line != null) { 
      String[] sp = line.split("\t| "); 
      double c = Double.parseDouble(sp[0]); 
      centers_next.add(c); 
      line = br.readLine(); 
     } 
     br.close(); 
     String prev; 
     if (iteration == 0) { 
      prev = input + CENTROID_FILE_NAME; 
     } else { 
      prev = again_input + OUTPUT_FILE_NAME; 
     } 
     Path prevfile = new Path(prev); 
     FileSystem fs1 = FileSystem.get(new URI("hdfs://127.0.0.1:9000"), configuration); 
     BufferedReader br1 = new BufferedReader(new InputStreamReader(fs1.open(prevfile))); 
     List<Double> centers_prev = new ArrayList<Double>(); 
     String l = br1.readLine(); 
     while (l != null) { 
      String[] sp1 = l.split(SPLITTER); 
      double d = Double.parseDouble(sp1[0]); 
      centers_prev.add(d); 
      l = br1.readLine(); 
     } 
     br1.close(); 
     Collections.sort(centers_next); 
     Collections.sort(centers_prev); 
     Iterator<Double> it = centers_prev.iterator(); 
     for (double d : centers_next) { 
      double temp = it.next(); 
      if (Math.abs(temp - d) <= 0.1) { 
       isdone = true; 
      } else { 
       isdone = false; 
       break; 
      } 
     } 
     ++iteration; 
     again_input = output; 
     output = OUT + System.nanoTime(); 
    } 
    long endTime = System.currentTimeMillis(); 
    long totalTime = endTime - startTime; 
    System.out.println(totalTime); 
} 

PS:ここ

は、関数がどのように見えるか、メインです。私はHadoopとMapReduceを初めて使用しています。

+0

HDFSからファイルを読む前に仕事が完了するのを待つべきでしょう。 –

+0

@Ahsan:パフォーマンスチューニングの部分を探しています。そのため、マッパーとレデューサーの数を設定してみてください。 –

+0

@ ramprasad-gはい、私はスピードアップを計算していると言っています。私はノードの数を増やすことによってスピードアップを得ました。今度はマッパーとレデューサーの数を増やしてシングルノードで計算したいと思います。 –

答えて

2

特定のジョブのマップ数は、通常、入力ファイル内の入力分割の数によって決定され、setNumMapTasks()またはmapred.map.tasksパラメータでは決まりません。 Mapタスクは入力分割ごとに生成されます。 mapred.map.tasksパラメータはマップの数に対するInputFormatのヒントに過ぎません。 setNumMapTasks()を使用してマップタスクの数を手動で増やすことができます。マップタスクの数を増やすために使用できますが、Hadoopが入力データを分割して決定する数よりも少ない数に設定しません。

http://wiki.apache.org/hadoop/HowManyMapsAndReduces

1

はい。

setNumMapTasksまたはconf.set('mapred.map.tasks','numberofmappersyouwanttoset')を使用してマッパーの数を変更することはできますが(ただし設定に提案があります)、マッパーインスタンスが設定される保証はありません。 さらに、それはinputsplitsに依存します。

還元剤の数も変更できます。あなたが書いたコードの種類を使用します。

結論: - (。実際には、入力ファイルのブロックの合計数すなわちinputsplits に基づいて)マップの数に設定

減速機の数を設定する提案を

- 需要

numbe rからのマ​​ッパーとレデューサーの答えは@ radkris、plsです。 thisをご覧ください。

1

Apache Map Reduce Tutorialはさらに詳しい情報を提供します。

どのくらいのマップですか?

マップの数は、通常は、入力ファイルのブロックの総数である入力の合計サイズ、によって駆動されます。それは非常にCPU-ライトマップタスクのための300枚のマップに設定されているが

マップの並列処理の適切なレベルは、ノードごと周り10-100マップのようです。タスクの設定にはしばらく時間がかかるため、マップの実行に最低1分かかる場合が最適です。

したがって、入力データが10TBでブロックサイズが128MBの場合、Configuration.set(MRJobConfig.NUM_MAPS, int)(フレームワークのヒントのみを提供する)を使用してさらに高い値に設定しない限り、最終的には82,000のマップになります。

+0

'マップのための適切なレベルの並列処理は、ノードごとに約10-100マップと思われる'それはあなたのハードウェアのセットアップに大きく依存しています。何を最大限に活用していますか?ネットワーク帯域幅、ディスク帯域幅? –