2013-05-29 8 views
6

私の入力データはhdfsです。私は単に言葉遣いをしようとしていますが、わずかな違いがあります。 データはjson形式です。 ので、データの各行は、次のとおりです。hadoop javaでjson入力を解析しています

{"author":"foo", "text": "hello"} 
{"author":"foo123", "text": "hello world"} 
{"author":"foo234", "text": "hello this world"} 

は、私が唯一の「テキスト」の部分に単語の語数をしたいです。

どうすればよいですか?

私はこれまでのところ、以下のバリアントを試してみました:

public static class TokenCounterMapper 
    extends Mapper<Object, Text, Text, IntWritable> { 
    private static final Log log = LogFactory.getLog(TokenCounterMapper.class); 
    private final static IntWritable one = new IntWritable(1); 
    private Text word = new Text(); 

    public void map(Object key, Text value, Context context) 
     throws IOException, InterruptedException { 
     try { 

      JSONObject jsn = new JSONObject(value.toString()); 

      //StringTokenizer itr = new StringTokenizer(value.toString()); 
      String text = (String) jsn.get("text"); 
      log.info("Logging data"); 
      log.info(text); 
      StringTokenizer itr = new StringTokenizer(text); 
      while (itr.hasMoreTokens()) { 
       word.set(itr.nextToken()); 
       context.write(word, one); 
      } 
     } catch (JSONException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
    } 
} 

をしかし、私はこのエラーを取得しています:

Error: java.lang.ClassNotFoundException: org.json.JSONException 
    at java.net.URLClassLoader$1.run(URLClassLoader.java:202) 
    at java.security.AccessController.doPrivileged(Native Method) 
    at java.net.URLClassLoader.findClass(URLClassLoader.java:190) 
    at java.lang.ClassLoader.loadClass(ClassLoader.java:306) 
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301) 
    at java.lang.ClassLoader.loadClass(ClassLoader.java:247) 
    at java.lang.Class.forName0(Native Method) 
    at java.lang.Class.forName(Class.java:247) 
    at org.apache.hadoop.conf.Configuration.getClassByName(Configuration.java:820) 
    at org.apache.hadoop.conf.Configuration.getClass(Configuration.java:865) 
    at org.apache.hadoop.mapreduce.JobContext.getMapperClass(JobContext.java:199) 
    at org.apache.hadoop.mapred.MapTask.runNewMapper(MapTask.java:719) 
    at org.apache.hadoop.mapred.MapTask.run(MapTask.java:370) 
    at org.apache.hadoop.mapred.Child$4.run(Child.java:255) 
    at java.security.AccessController.doPrivileged(Native Method) 
    at javax.security.auth.Subject.doAs(Subject.java:396) 
    at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1093) 
    at org.apache.hadoop.mapred.Child.main(Child.java:249) 
+4

彼は現在コードを掲載しており、重複しているわけではないので、5歳のようなものすべてをdownvoteしないでください。 ;) –

+1

豚はそれを行うためのより良い選択、IMHOでしょう。なぜ私は一部の人々がダウンボウティングに非常に喜んでいるのか分かりません。あなたが本当にそれをしたいのであれば、賢明な理由を提供するのに十分親切にしてください。これが、人々がクオラのような他の場所に移動する理由です。 – Tariq

答えて

3

はあなたのHadoopジョブジャーにJSONライブラリを埋め込むために忘れてしまったようです。あなたはライブラリとあなたの仕事を構築する方法を確認するためにそこに見ることができ : http://tikalk.com/build-your-first-hadoop-project-maven

+0

おそらく。しかし、私はenvとしてEclipseを使用しています。私はローカルマシン上でjarファイルを作成することはできますが、次にこのjarファイルをクラスタにsshingしていますか? – Fraz

+1

Eclispeで実行するコードは、クラスパス設定のために動作する可能性がありますが、Hadoopクラスタにデプロイされた最終ジョブにライブラリを埋め込む必要があります。実行時にクラスが見つからない(文字通り存在しないため) 。 – clement

+0

THanks for insight ..私はこれを追加しました。-D mapred.child.env = "LD_LIBRARY_PATH =/examples/wordcount/json-20090211.jar"しかし、同じエラー:( – Fraz

1

をコードを減らすあなたのマップと外部のjarファイルを使用するには、いくつかの方法があります。

  1. は、参照JARを含めますサブミット可能なJARのlibサブディレクトリにあります。ジョブは、このlibサブディレクトリのJARをそれぞれのTaskTrackerノードのジョブキャッシュに展開し、このディレクトリにタスクをポイントしてJARをコードで使用できるようにします。 JARが小さく、頻繁に変更され、ジョブ固有の場合、これが推奨される方法です。これは彼の答えに示唆されているものです@clement

  2. クラスタノードにJARをインストールします。最も簡単な方法は、JARを$HADOOP_HOME/libディレクトリに置くことです.Hadoopデーモンの起動時にこのディレクトリのすべてが含まれるためです。これを有効にするにはスタートストップが必要であることに注意してください。

  3. TaskTrackersは外部JARを使用するため、設定ファイルのHADOOP_TASKTRACKER_OPTSオプションを変更して提供し、jarをポイントします。 jarファイルは、タスクトラッカーが動作するすべてのノード上の同じパスに存在する必要があります。

  4. hadoop jar …コマンドの "-libjars"コマンドラインオプションにJARを含めます。 jarは分散キャッシュに置かれ、ジョブのすべてのタスクの試行で使用できるようになります。 map-reduceコードにはGenericOptionsParserを使用する必要があります。詳細はthis blog postをご覧ください。

比較:それは大きな負のパフォーマンスコストを持っているので、

  • 1は、従来の方法ではなく、お勧めです。

  • 2と#3はプライベートクラスタには適していますが、エンドユーザーには期待できないほど怠惰な方法です。

  • 4が最も推奨されるオプションです。

Clouderaからmain postを読みます)。

関連する問題