2012-06-27 8 views
7

Tôi đã viết một chương trình Mapreduce trong Java, mà tôi có thể gửi đến một cụm từ xa đang chạy trong chế độ phân tán. Hiện nay, tôi gửi công việc sử dụng các bước sau:Khởi chạy một công việc Mapreduce từ eclipse

  1. xuất khẩu công việc mapreuce như một jar (ví dụ myMRjob.jar)
  2. trình công việc để cụm từ xa bằng cách sử dụng lệnh shell sau: hadoop jar myMRjob.jar

Tôi muốn gửi công việc trực tiếp từ Eclipse khi tôi cố gắng chạy chương trình. Tôi có thể làm cái này như thế nào?

Tôi hiện đang sử dụng CDH3, và một phiên bản rút gọn của conf của tôi là:

conf.set("hbase.zookeeper.quorum", getZookeeperServers()); 
conf.set("fs.default.name","hdfs://namenode/"); 
conf.set("mapred.job.tracker", "jobtracker:jtPort"); 
Job job = new Job(conf, "COUNT ROWS"); 
job.setJarByClass(CountRows.class); 

// Set up Mapper 
TableMapReduceUtil.initTableMapperJob(inputTable, scan, 
    CountRows.MyMapper.class, ImmutableBytesWritable.class, 
    ImmutableBytesWritable.class, job); 

// Set up Reducer 
job.setReducerClass(CountRows.MyReducer.class); 
job.setNumReduceTasks(16); 

// Setup Overall Output 
job.setOutputFormatClass(MultiTableOutputFormat.class); 

job.submit(); 

Khi tôi chạy trực tiếp từ Eclipse, công việc được đưa ra nhưng Hadoop không thể tìm thấy người vẽ bản đồ/hạ. Tôi nhận được các lỗi sau:

12/06/27 23:23:29 INFO mapred.JobClient: map 0% reduce 0% 
12/06/27 23:23:37 INFO mapred.JobClient: Task Id : attempt_201206152147_0645_m_000000_0, Status : FAILED 
java.lang.RuntimeException: java.lang.ClassNotFoundException: com.mypkg.mapreduce.CountRows$MyMapper 
    at org.apache.hadoop.conf.Configuration.getClass(Configuration.java:996) 
    at org.apache.hadoop.mapreduce.JobContext.getMapperClass(JobContext.java:212) 
    at org.apache.hadoop.mapred.MapTask.runNewMapper(MapTask.java:602) 
    at org.apache.hadoop.mapred.MapTask.run(MapTask.java:323) 
    at org.apache.hadoop.mapred.Child$4.run(Child.java:270) 
    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:1127) 
    at org.apache.hadoop.mapred.Child.main(Child.java:264) 
... 

Có ai biết cách vượt qua các lỗi này không? Nếu tôi có thể sửa lỗi này, tôi có thể tích hợp nhiều công việc MR vào các tập lệnh của tôi, điều này thật tuyệt vời!

+0

Tucker - Tôi đã có thể chạy các công việc Hadoop trong độc lập, nhưng không phải chế độ khác từ Eclipse. Tôi đã đăng truy vấn trong diễn đàn Hadoop một thời gian và không có phản hồi nào. BTW, Hadoop chạy ở chế độ độc lập mà không có bất kỳ tệp cấu hình nào (các tham số mặc định). –

+0

Khi bạn gửi công việc từ bên trong Eclipse, các lớp bản đồ/giảm tốc trong cùng một dự án, hay là bình chứa chúng trên đường dẫn lớp, và các lớp của chúng không ở đâu khác trên cp? –

+0

@ChrisWhite Lớp chứa tất cả mọi thứ được gọi là CountRows. Lớp này chứa một phương thức 'chính' đặt cấu hình công việc. lớp CountRows cũng chứa lớp cho trình ánh xạ và trình giảm tốc được gọi là MyMapper và MyReducer tương ứng. Công việc hoạt động tốt như tôi đã nói khi tôi khởi chạy công việc từ comandline bằng cách viết 'hadoop jar CountRows.jar' – Tucker

Trả lời

8

Nếu bạn đang gửi công việc hadoop từ bên trong dự án Eclipse xác định các lớp cho công việc thì bạn có thể gặp vấn đề về classpath nhất.

Cuộc gọi job.setjarByClass(CountRows.class) đang tìm tệp lớp trên đường dẫn lớp xây dựng, chứ không phải trong tệp CountRows.jar (có thể hoặc chưa được xây dựng hoặc thậm chí trên đường dẫn lớp).

Bạn có thể khẳng định điều này là đúng bằng cách in kết quả của job.getJar() sau khi bạn gọi job.setjarByClass(..) và nếu nó không hiển thị một tệp jar, thì nó sẽ tìm thấy lớp dựng, chứ không phải lớp jar'd

+0

Ok, tôi đã chạy "job.setJarByClass (CountRows.class); \t \t System.out.println (" getClass ...: "+ job.getClass());" và kết quả chỉ đơn giản là "getClass ...: class org.apache.hadoop.mapreduce.Job" – Tucker

+0

Thật không ngạc nhiên khi bạn hỏi loại công việc. Hãy thử 'job.getJar()' thay vì 'job.getClass()' –

+0

Ha, phương pháp sai trái của bạn! Tôi chạy nó ngay bây giờ, nó nói null của nó. Có cách nào để làm cho nó hoạt động khi tôi chạy chương trình qua nhật thực? – Tucker

1

tôi đã sử dụng phương pháp này từ trang web sau đây để cấu hình một bản đồ/Giảm dự án của tôi để chạy các dự án sử dụng Eclipse (w/o xuất khẩu dự án như JAR) Configuring Eclipse to run Hadoop Map/Reduce project

Lưu ý: Nếu bạn quyết định để gỡ lỗi chương trình của bạn, lớp học Mapper và lớp Reducer của bạn sẽ không thể gỡ lỗi được.

Hy vọng điều đó sẽ hữu ích. :)

+1

Bạn nên cung cấp bản tóm tắt giải pháp không chỉ cung cấp liên kết có thể biến mất – Mark

+1

Bạn đã nói "Nếu bạn quyết định gỡ lỗi chương trình của mình, lớp Mapper và lớp Reducer của bạn sẽ không thể gỡ lỗi". tại sao điều này và nó luôn luôn đúng? – John

2

Điều gì làm việc cho tôi là xuất JAR chạy được (sự khác biệt giữa nó và JAR là định nghĩa lớp đầu tiên, có phương thức chính) và chọn tùy chọn "đóng gói thư viện yêu cầu vào JAR" tùy chọn "extracting ..." dẫn đến các lỗi trùng lặp và nó cũng phải trích xuất các tệp lớp từ các lọ, mà cuối cùng, trong trường hợp của tôi, dẫn đến việc không giải quyết ngoại lệ của lớp không tìm thấy).

Sau đó, bạn chỉ có thể đặt bình, như được đề xuất bởi Chris White. Đối với Windows nó sẽ trông như thế này: job.setJar("C:\\\MyJar.jar");

Nếu nó giúp bất cứ ai, tôi đã thực hiện một bài thuyết trình về những gì tôi học được từ creating a MapReduce project and running it in Hadoop 2.2.0 in Windows 7 (in Eclipse Luna)