2012-07-28 47 views
13

Tôi đang làm việc với Hadoop và tôi cần phải tìm thấy 100 tệp nào trong hệ thống tệp Hadoop của tôi chứa một chuỗi nhất định.Grep trên nhiều tệp trong Hệ thống tệp Hadoop

tôi có thể xem các tập tin Tôi muốn tìm kiếm như thế này:

bash-3.00$ hadoop fs -ls /apps/mdhi-technology/b_dps/real-time 

đồi khế, đồi trả về một số mục như thế này:

-rw-r--r-- 3 b_dps mdhi-technology 1073741824 2012-07-18 22:50 /apps/mdhi-technology/b_dps/HADOOP_consolidated_RT_v1x0_20120716_aa 
-rw-r--r-- 3 b_dps mdhi-technology 1073741824 2012-07-18 22:50 /apps/mdhi-technology/b_dps/HADOOP_consolidated_RT_v1x0_20120716_ab 

Làm thế nào để tìm thấy trong đó những chứa chuỗi bcd4bc3e1380a56108f486a4fffbc8dc ? Khi tôi biết, tôi có thể chỉnh sửa chúng theo cách thủ công.

+0

Grep hoặc Sed? Không? – plast1K

+0

Vấn đề với điều này là, nó không phải là một hệ thống tập tin UNIX, một hệ thống tệp Hadoop của nó, bất cứ khi nào tôi cố gắng làm như thế này 'bash-3.00 $ cd/apps/hdmi-công nghệ/b_dps/thời gian thực bash: cd:/apps/hdmi-technology/b_dps/thời gian thực: Không có tệp hoặc thư mục nào' Tôi không nhận được tệp hoặc thư mục như vậy. Vì vậy, tôi cần một số cách khác để giải quyết vấn đề này. – ferhan

Trả lời

28

Đây là một hadoop "hệ thống tập tin", không phải là một POSIX một, vì vậy hãy thử này:

hadoop fs -ls /apps/hdmi-technology/b_dps/real-time | awk '{print $8}' | \ 
while read f 
do 
    hadoop fs -cat $f | grep -q bcd4bc3e1380a56108f486a4fffbc8dc && echo $f 
done 

này nên làm việc, nhưng nó là nối tiếp và như vậy có thể được làm chậm. Nếu cluster của bạn có thể mất nhiệt, chúng ta có thể parallelize:

hadoop fs -ls /apps/hdmi-technology/b_dps/real-time | awk '{print $8}' | \ 
    xargs -n 1 -I^-P 10 bash -c \ 
    "hadoop fs -cat^| grep -q bcd4bc3e1380a56108f486a4fffbc8dc && echo ^" 

Thông báo các -P 10 tùy chọn để xargs: đây là bao nhiêu tập tin chúng tôi sẽ tải về và tìm kiếm song song. Bắt đầu thấp và tăng số lượng cho đến khi bạn bão hòa I/O đĩa hoặc băng thông mạng, bất cứ điều gì có liên quan trong cấu hình của bạn.

EDIT: Cho rằng bạn đang ở trên SunOS (đó là hơi chết não) thử này:

hadoop fs -ls /apps/hdmi-technology/b_dps/real-time | awk '{print $8}' | while read f; do hadoop fs -cat $f | grep bcd4bc3e1380a56108f486a4fffbc8dc >/dev/null && echo $f; done 
+0

Vấn đề với điều này là, nó không phải là hệ thống tệp UNIX, hệ thống tệp Hadoop của nó, bất cứ khi nào tôi cố gắng thực hiện như thế này 'bash-3.00 $ cd/apps/hdmi-công nghệ/b_dps/thời gian thực bash: cd:/ứng dụng/hdmi-công nghệ/b_dps/thời gian thực: Không có tệp hoặc thư mục nào' Tôi không nhận được tệp hoặc thư mục như vậy. – ferhan

+0

Bạn đang tích cực thư mục này tồn tại? Bạn có thể gắn nó vào một vị trí, và sau đó cd vào nó? – plast1K

+0

Tôi không chắc liệu tôi có thể làm điều này hay không vì thư mục đó có TB dữ liệu bên trong. Và làm thế nào tôi có thể gắn nó vào một vị trí bằng cách này? – ferhan

0

Sử dụng hadoop fs -cat (hoặc chung chung hơn hadoop fs -text) có thể là khả thi nếu bạn chỉ có hai 1 GB tệp. Đối với 100 tập tin mặc dù tôi sẽ sử dụng streaming-api vì nó có thể được sử dụng cho truy vấn adhoc mà không cần đến một công việc bản đồ đầy đủ chính xác. Ví dụ. trong trường hợp của bạn tạo ra một kịch bản get_filename_for_pattern.sh:

#!/bin/bash 
grep -q $1 && echo $mapreduce_map_input_file 
cat >/dev/null # ignore the rest 

Lưu ý rằng bạn phải đọc toàn bộ đầu vào, để tránh bị java.io.IOException: Stream closed trường hợp ngoại lệ.

Sau đó ban hành các lệnh

hadoop jar $HADOOP_HOME/hadoop-streaming.jar\ 
-Dstream.non.zero.exit.is.failure=false\ 
-files get_filename_for_pattern.sh\ 
-numReduceTasks 1\ 
-mapper "get_filename_for_pattern.sh bcd4bc3e1380a56108f486a4fffbc8dc"\ 
-reducer "uniq"\ 
-input /apps/hdmi-technology/b_dps/real-time/*\ 
-output /tmp/files_matching_bcd4bc3e1380a56108f486a4fffbc8dc 
hadoop fs -cat /tmp/files_matching_bcd4bc3e1380a56108f486a4fffbc8dc/* 

Trong các bản phân phối mới hơn mapred streaming thay vì hadoop jar $HADOOP_HOME/hadoop-streaming.jar nên làm việc. Trong trường hợp sau, bạn phải cài đặt chính xác $HADOOP_HOME để tìm bình (hoặc cung cấp đường dẫn đầy đủ trực tiếp).

Để truy vấn đơn giản hơn, bạn thậm chí không cần tập lệnh nhưng chỉ có thể cung cấp lệnh trực tiếp cho thông số -mapper. Nhưng đối với bất cứ điều gì hơi phức tạp, nó thích hợp hơn để sử dụng một kịch bản, bởi vì nhận được quyền thoát có thể là một việc vặt.

Nếu bạn không cần pha giảm cung cấp thông số NONE tượng trưng cho tùy chọn -reduce tương ứng (hoặc chỉ sử dụng -numReduceTasks 0). Nhưng trong trường hợp của bạn, nó hữu ích khi có một pha giảm để có kết quả đầu ra được hợp nhất thành một tệp duy nhất.

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