2013-05-29 12 views
6

मेरा इनपुट डेटा hdfs में है। मैं बस शब्द गणना करने की कोशिश कर रहा हूं लेकिन थोड़ा अंतर है। डेटा जेसन प्रारूप में है। तो डेटा की प्रत्येक पंक्ति है:पार्सिंग जेसन इनपुट हडूप जावा

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

मैं केवल "पाठ" भाग में शब्दों का wordcount करना चाहते हैं।

मैं यह कैसे कर सकता हूं?

मैं अब तक निम्नलिखित संस्करण की कोशिश की:

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

उन्होंने अब कोड पोस्ट किया है और कोई डुप्लिकेट नहीं है, इसलिए पांच वर्षीय की तरह सबकुछ कम न करें। ;) –

+1

पिग ऐसा करने के लिए बेहतर विकल्प होगा, आईएमएचओ। और मुझे नहीं पता कि क्यों कुछ लोग डाउनवॉटिंग में बहुत आनंद लेते हैं। और यदि आप वास्तव में ऐसा करना चाहते हैं, तो कृपया कुछ समझदार कारण प्रदान करने के लिए पर्याप्त दयालु रहें। यही वजह है कि लोग क्वारा जैसे अन्य स्थानों पर जा रहे हैं। संभवतः – Tariq

उत्तर

3

लगता है कि आप अपने Hadoop काम जार में JSON पुस्तकालय एम्बेड करने के लिए भूल गया था। आप एक बार देख वहाँ कैसे आप लाइब्रेरी के साथ अपने काम का निर्माण कर सकते देखने के लिए कर सकते हैं: http://tikalk.com/build-your-first-hadoop-project-maven

+0

। लेकिन मैं ग्रहण के रूप में ग्रहण का उपयोग कर रहा हूं .. मैं अपनी स्थानीय मशीन पर सफलतापूर्वक जार फ़ाइल बनाने में सक्षम हूं लेकिन फिर मैं अपने क्लस्टर में इस जार को झुका रहा हूं ?? – Fraz

+1

आपके द्वारा क्लासपाथ कॉन्फ़िगरेशन के कारण चलने वाला कोड आपके क्लासपाथ कॉन्फ़िगरेशन के कारण काम कर सकता है, लेकिन आपको अभी भी अपने हैडॉप क्लस्टर पर तैनात अंतिम नौकरी में या अपने रनबाइम पर अपनी लाइब्रेरी एम्बेड करने की आवश्यकता है, क्योंकि क्लास नहीं मिलेगा (क्योंकि वे सचमुच मौजूद नहीं हैं) । – clement

+0

अंतर्दृष्टि के लिए धन्यवाद .. मैंने यह जोड़ा-D mapred.child.env = "LD_LIBRARY_PATH =/उदाहरण/wordcount/json-20090211.jar" लेकिन फिर भी वही त्रुटि :( – Fraz

1

आपके नक्शे के साथ बाहरी जार उपयोग करने के लिए कोड को कम कई तरीके हैं:

  1. संदर्भित जार शामिल करें सबमिट करने योग्य जार की लिब उपनिर्देशिका में: नौकरी इस lib उपनिर्देशिका से जेएआर को संबंधित टास्कट्रैकर नोड्स पर जॉब कैश में अनपैक कर देगा और आपके कार्यों को JAR को आपके कोड में उपलब्ध कराने के लिए इस निर्देशिका में इंगित करेगी। यदि जार छोटे होते हैं, अक्सर बदलते हैं, और नौकरी-विशिष्ट हैं तो यह पसंदीदा तरीका है। @clement ने अपने उत्तर में यह सुझाव दिया है।

  2. क्लस्टर नोड्स पर जेएआर स्थापित करें। सबसे आसान तरीका है JAR को $HADOOP_HOME/lib निर्देशिका में रखना है क्योंकि इस निर्देशिका से सब कुछ शामिल है जब एक हैडोप डिमन शुरू होता है। ध्यान दें कि इसे प्रभावी बनाने के लिए एक स्टार्ट स्टॉप की आवश्यकता होगी।

  3. टास्कट्रैकर बाहरी जेएआर का उपयोग करेंगे, इसलिए आप इसे HADOOP_TASKTRACKER_OPTS विकल्प hadoop-env.sh कॉन्फ़िगरेशन फ़ाइल में संशोधित करके प्रदान कर सकते हैं और इसे जार को इंगित कर सकते हैं। जार को उन सभी नोड्स पर उसी पथ पर मौजूद होना चाहिए जहां कार्य-ट्रैकर चलता है।

  4. hadoop jar … कमांड के "-libjars" कमांड लाइन विकल्प में JAR शामिल करें। जार वितरित कैश में रखा जाएगा और सभी नौकरी के कार्य प्रयासों के लिए उपलब्ध कराया जाएगा। आपके मानचित्र-कम कोड को GenericOptionsParser का उपयोग करना चाहिए। अधिक जानकारी के लिए this blog post पढ़ें।

तुलना: क्योंकि यह एक बड़ी नकारात्मक प्रदर्शन लागत है

  • 1 एक विरासत विधि लेकिन हतोत्साहित है।

  • 2 और # 3 निजी क्लस्टर के लिए अच्छे हैं लेकिन बहुत लंगड़ा अभ्यास है क्योंकि आप अंतिम उपयोगकर्ताओं को ऐसा करने की उम्मीद नहीं कर सकते हैं।

  • 4 सबसे अधिक अनुशंसित विकल्प है।

क्लौडेरा से main post पढ़ें)।

संबंधित मुद्दे