2012-03-13 29 views
21

Tôi có một loạt tệp nhỏ trong thư mục HDFS. Mặc dù khối lượng tệp tương đối nhỏ, lượng thời gian xử lý cho mỗi tệp là rất lớn. Tức là, tệp 64mb, là kích thước phân chia mặc định cho TextInputFormat, sẽ mất vài giờ để xử lý.Thay đổi kích thước Tách tệp trong Hadoop

Những gì tôi cần làm, là giảm kích thước chia, để tôi có thể sử dụng nhiều nút hơn cho công việc.

Vì vậy, câu hỏi đặt ra là làm cách nào để chia nhỏ tệp bằng cách giả sử 10kb? Tôi có cần triển khai InputFormatRecordReader cho riêng mình hay không hoặc có bất kỳ thông số nào để đặt không? Cảm ơn.

Trả lời

32

Tham số mapred.max.split.size có thể được đặt cho mỗi công việc riêng lẻ là những gì bạn đang tìm kiếm. Không thay đổi dfs.block.size vì đây là toàn cầu cho HDFS và có thể dẫn đến sự cố.

+12

dfs.block.size không nhất thiết là toàn cầu; bạn có thể đặt các tệp cụ thể để có kích thước khối khác với kích thước mặc định cho hệ thống tệp của bạn. Tôi đồng ý rằng mapred.max.split.size có lẽ là cách để đi trong trường hợp này, mặc dù. – ajduff574

+0

['mapred.max.split.size' không được chấp nhận. Tên thuộc tính mới là 'mapreduce.input.fileinputformat.split.maxsize'] (https://hadoop.apache.org/docs/current/hadoop-project-dist/hadoop-common/DeprecatedProperties.html). Tôi cũng tìm thấy [câu trả lời này] (https://stackoverflow.com/questions/19188315/behavior-of-the-parameter-mapred-min-split-size-in-hdfs) rất hữu ích để điều chỉnh kích thước phân chia đầu vào. –

-1

"Hadoop: Hướng dẫn dứt khoát", tr. 202:

Cho một tập hợp các tệp, FileInputFormat biến chúng thành các phần tách như thế nào? FileInputFormat chỉ tách các tệp lớn. Ở đây "lớn" có nghĩa là lớn hơn một khối HDFS. Kích thước phân chia thường là kích thước của khối HDFS .

Vì vậy, bạn nên thay đổi kích thước của khối HDFS, nhưng điều này là sai. Có lẽ bạn nên thử xem lại kiến ​​trúc của ứng dụng MapReduce của bạn.

+0

vì nó nói "thông thường", không phải "luôn luôn", tôi nghĩ rằng nên có một cách xung quanh. – Ahmedov

+5

Thử đặt các tùy chọn "mapreduce.input.fileinputformat.split.maxsize" và "mapreduce.input.fileinputformat.split.minsize". FileInputFormat.computeSplitSize() trả về Math.max (minSize, Math.min (maxSize, blockSize)). Vì vậy, kích thước phân chia có thể thấp hơn kích thước khối (theo các nguồn lớp FileInputFormat). –

21

Hướng dẫn dứt khoát Hadoop, trang 203 "Kích thước phân chia tối đa mặc định là giá trị lớn nhất có thể được biểu diễn bằng loại dài Java. Nó chỉ có hiệu lực khi nó nhỏ hơn kích thước khối, buộc chia tách . nhỏ hơn so với một khối Kích thước chia được tính theo công thức:

max(minimumSize, min(maximumSize, blockSize)) 

theo mặc định

minimumSize < blockSize < maximumSize 

vì vậy kích thước chia là blockSize

Ví dụ,

Minimum Split Size 1 
Maximum Split Size 32mb 
Block Size 64mb 
Split Size 32mb 

Hadoop Làm việc tốt hơn với một số lượng nhỏ các file lớn hơn một số lượng lớn các tập tin nhỏ. Một lý do cho điều này là FileInputFormat tạo ra các phân chia theo cách mà mỗi phần tách là tất cả hoặc một phần của một tệp. Nếu tệp rất nhỏ ("nhỏ" có nghĩa là nhỏ hơn đáng kể so với khối HDFS) và có rất nhiều tệp, thì mỗi tác vụ trên bản đồ sẽ xử lý rất ít đầu vào và sẽ có rất nhiều tệp (mỗi tệp cho một tệp), mỗi trong số đó áp đặt thêm chi phí kế toán. So sánh một tệp 1gb được chia thành sáu mươi khối 64mb và 10.000 tệp hoặc 100kb. 10.000 tệp sử dụng một bản đồ, và thời gian công việc có thể chậm hơn hàng chục hoặc hàng trăm lần so với một tệp tương đương với một tệp đầu vào đơn và 16 tác vụ bản đồ.


1

Viết định dạng đầu vào tùy chỉnh mở rộng kết hợpfileinputformat [có ưu điểm riêng biệt của nó sẽ phân phối phân phối hadoop]. kết hợp đầu vào tách thành giá trị được chỉ định trong mapred.max.split.size

2

Đây là đoạn minh họa cách chính xác để thực hiện những gì cần ở đây mà không cần chuỗi cấu hình ma thuật. Hằng số cần thiết được xác định bên trong FileInputFormat. Khối kích thước có thể được thực hiện nếu cần thiết từ khối mặc định HDFS khối nhưng nó có xác suất khá tốt để được người dùng xác định.

Ở đây tôi chỉ chia kích thước chia tối đa cho 2 nếu được xác định.

import org.apache.hadoop.conf.Configuration; 
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat; 

// .... 

final long DEFAULT_SPLIT_SIZE = 128 * 1024 * 1024; 
final Configuration conf = ... 

// We need to lower input block size by factor of two. 
conf.setLong(
    FileInputFormat.SPLIT_MAXSIZE, 
    conf.getLong(
     FileInputFormat.SPLIT_MAXSIZE, DEFAULT_SPLIT_SIZE)/2); 
Các vấn đề liên quan