2012-04-18 33 views
21

Tôi đang làm việc trên một công việc mà xử lý một cấu trúc thư mục lồng nhau, chứa các tập tin trên nhiều cấp độ:Hadoop MapReduce cung cấp các thư mục lồng nhau như đầu vào công việc

one/ 
├── three/ 
│   └── four/ 
│    ├── baz.txt 
│    ├── bleh.txt 
│    └── foo.txt 
└── two/ 
    ├── bar.txt 
    └── gaa.txt 

Khi tôi thêm one/ như một con đường đầu vào, không có tập tin là được xử lý, vì không có dữ liệu nào có sẵn ngay ở cấp cơ sở.

Tôi đọc khoảng job.addInputPathRecursively(..), nhưng điều này dường như đã không được chấp nhận trong các bản phát hành gần đây hơn (tôi đang sử dụng hadoop 1.0.2). Tôi đã viết một số mã để đi bộ các thư mục và thêm mỗi thư mục với job.addInputPath(dir), hoạt động cho đến khi lệnh bị lỗi khi cố gắng xử lý thư mục dưới dạng tệp đầu vào vì một số lý do, ví dụ: - cố gắng fs.open(split.getPath()), khi split.getPath() là một thư mục (Điều này xảy ra bên trong LineRecordReader.java).

Tôi đang cố thuyết phục bản thân rằng phải có cách đơn giản hơn để cung cấp công việc với cấu trúc thư mục lồng nhau. Bất kỳ ý tưởng?

CHỈNH SỬA - dường như có open bug về điều này.

+3

Việc sử dụng 'FileSystem # listStatus()' có bổ sung thêm không? –

+0

Tôi đang giải quyết nó theo cách tương tự - đã viết mã đệ quy mà đi qua thư mục con và thêm tất cả các tệp vào Đường dẫn –

+1

@ThomasJungblut đó là cách tiếp cận cơ bản hiện tại của tôi. Tôi chỉ thấy nó kỳ lạ là chức năng này không được tích hợp.Một vấn đề khác mà tôi gặp phải là sự cố hadoop khi nó truy cập vào một thư mục con mà không có bất kỳ tệp nào trong đó, chỉ các thư mục khác (như 'one' và' one/three' trong ví dụ của tôi). Vì vậy, về cơ bản tôi cần phải thực hiện logic sẽ thêm thư mục đệ quy trừ khi họ ** chỉ ** có các thư mục khác trong đó, thay vì tệp (vẫn phải đi bộ nội dung của họ để thêm tệp lồng nhau). Có vẻ như rất nhiều rắc rối chỉ để thiết lập một công việc. – sa125

Trả lời

4

Tôi tìm thấy đệ quy thông qua dữ liệu có thể nguy hiểm vì có thể có các tệp nhật ký kéo dài từ một số distcp hoặc tương tự. Hãy để tôi đề xuất một giải pháp thay thế:

Thực hiện thao tác đệ quy trên dòng lệnh và sau đó chuyển vào đường dẫn trong tham số được phân tách bằng dấu cách trong chương trình MapReduce của bạn. Lấy danh sách từ argv:

$ hadoop jar blah.jar "`hadoop fs -lsr recursivepath | awk '{print $8}' | grep '/data.*\.txt' | tr '\n' ' '`" 

Xin lỗi vì sự bash dài, nhưng nó được công việc làm. Bạn có thể bọc những thứ trong một kịch bản bash để phá vỡ mọi thứ thành các biến. Cá nhân tôi thích cách tiếp cận pass-in-filepath để viết các công việc Mapreduce của tôi vì vậy bản thân mã không có đường dẫn mã cứng và nó tương đối dễ dàng để tôi thiết lập nó để chạy với danh sách các tập tin phức tạp hơn.

+0

Cảm ơn vì điều này. Bạn có biết nếu có bất kỳ lý do nào để làm điều đó theo cách này so với FileInputFormat.addInputPaths ("tệp phân cách bằng dấu phẩy từ bash bên trên")? – dranxo

+0

Thú vị, vì sao? Tôi khá mới với Hadoop nhưng đã gặp phải vấn đề này. – dranxo

-1

chỉ cần sử dụng FileInputFormat.addInputPath ("có mẫu tệp"); i am viết prog hadoop đầu tiên của tôi cho phân tích đồ thị, nơi đầu vào là từ thư mục khác trong định dạng .gz ... nó làm việc cho tôi !!!

+0

sử dụng mẫu tên là một cách để tránh vấn đề thư mục lồng nhau. – hakunami

14

Tôi không tìm thấy bất kỳ tài liệu nào về việc này nhưng */* hoạt động. Vì vậy, nó là -input 'path/*/*'.

+0

u chắc chắn điều này không được mở rộng trong bash (hoặc vỏ của bạn) và tung ra tấn trường hợp hadoop? – jbu

+0

Tôi có dấu nháy đơn xung quanh. – Cheng

+0

Chạy 'ps -aux' sẽ giúp xóa vấn đề được đề cập bởi @jbu –

1

Không biết nếu vẫn còn có liên quan nhưng ít nhất trong hadoop 2.4.0 bạn có thể thiết lập thuộc tính mapreduce.input.fileinputformat.input.dir.recursive để đúng và nó sẽ giải quyết vấn đề của bạn.

6

nhập org.apache.hadoop.mapreduce.lib.input.FileInputFormat;

FileInputFormat.setInputDirRecursive (công việc, đúng);

Không, cảm ơn, chỉ cần gọi tôi là LeiFeng!

+0

haha ​​Xin chào LeiFeng, tôi rất thích đọc nhật ký ur :) – songyy

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