2013-05-29 49 views
6

Dữ liệu đầu vào của tôi ở định dạng hdfs. Tôi chỉ đơn giản là cố gắng để làm wordcount nhưng có sự khác biệt nhỏ. Dữ liệu ở định dạng json. Vì vậy, mỗi dòng dữ liệu là:phân tích cú pháp đầu vào json trong hadoop java

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

Tôi chỉ muốn đếm từ trong phần "văn bản".

Làm cách nào để thực hiện việc này?

Tôi đã thử các biến thể sau đây cho đến nay:

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(); 
     } 
    } 
} 

Nhưng tôi nhận được lỗi này:

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

Anh ấy đã đăng mã ngay bây giờ VÀ không trùng lặp, vì vậy đừng downvote mọi thứ như một đứa trẻ năm tuổi. ;) –

+1

Lợn sẽ là một lựa chọn tốt hơn để làm điều đó, IMHO. Và tôi không biết tại sao một số người lại có niềm vui to lớn trong việc bỏ phiếu. Và nếu bạn thực sự muốn làm điều đó, hãy tử tế, đủ để cung cấp một số lý do hợp lý. Đây là lý do mọi người di chuyển đến những nơi khác như Quora. – Tariq

Trả lời

3

Có vẻ bạn quên để nhúng thư viện JSON trong công việc jar Hadoop của bạn. Bạn có thể có một cái nhìn đó để xem làm thế nào bạn có thể xây dựng công việc của bạn với thư viện: http://tikalk.com/build-your-first-hadoop-project-maven

+0

Có thể. Nhưng tôi đang sử dụng eclipse như là một env .. Tôi có thể tạo file jar thành công trên máy địa phương của tôi nhưng sau đó tôi sshing jar này để cụm của tôi ?? – Fraz

+1

Mã bạn chạy trong Eclispe có thể hoạt động vì cấu hình classpath của bạn, nhưng bạn vẫn cần phải nhúng thư viện của mình vào Công việc cuối cùng được triển khai trên cụm Hadoop của bạn hoặc trong thời gian chạy, lớp sẽ không được tìm thấy (vì chúng không tồn tại theo nghĩa đen) . – clement

+0

THanks cho cái nhìn sâu sắc .. Tôi thêm này -D mapred.child.env = "LD_LIBRARY_PATH =/ví dụ/wordcount/json-20090211.jar" Nhưng vẫn còn lỗi tương tự: ( – Fraz

1

Có một số cách để sử dụng lọ bên ngoài với bản đồ của bạn giảm mã:

  1. Bao gồm JAR tham chiếu trong thư mục con lib của JAR không thể gửi được: Công việc sẽ giải nén JAR từ thư mục con lib này vào jobcache trên các nút TaskTracker tương ứng và trỏ các nhiệm vụ của bạn vào thư mục này để làm cho JAR có sẵn cho mã của bạn. Nếu các JAR nhỏ, thay đổi thường xuyên, và là công việc cụ thể, đây là phương pháp ưa thích. Đây là những gì @clement được đề xuất trong câu trả lời của anh ấy.

  2. Cài đặt JAR trên các nút cụm. Cách dễ nhất là đặt JAR vào thư mục $HADOOP_HOME/lib vì tất cả mọi thứ từ thư mục này được bao gồm khi một daemon Hadoop khởi động. Lưu ý rằng bắt đầu dừng sẽ là cần thiết để làm cho điều này có hiệu quả.

  3. TaskTrackers sẽ sử dụng JAR bên ngoài, vì vậy bạn có thể cung cấp nó bằng cách sửa đổi tùy chọn HADOOP_TASKTRACKER_OPTS trong tệp cấu hình hadoop-env.sh và đặt nó vào bình. Bình cần phải có mặt tại cùng một đường dẫn trên tất cả các nút mà công cụ theo dõi chạy.

  4. Bao gồm JAR trong tùy chọn dòng lệnh “-libjars” của lệnh hadoop jar …. Bình sẽ được đặt trong bộ nhớ cache được phân phối và sẽ có sẵn cho tất cả các lần thử nhiệm vụ của công việc. Mã giảm bản đồ của bạn phải sử dụng GenericOptionsParser. Để biết thêm chi tiết, hãy đọc this blog post.

So sánh:

  • 1 là một phương pháp di sản nhưng nản lòng bởi vì nó có một chi phí hiệu quả tiêu cực lớn.

  • 2 và # 3 rất phù hợp cho các nhóm riêng tư nhưng thực hành khá kém khi bạn không thể mong đợi người dùng cuối làm điều đó.

  • 4 là tùy chọn được đề xuất nhiều nhất.

Đọc main post từ Cloudera).

Các vấn đề liên quan