Hadoop sử dụng mô hình lập trình MapReduce để xử lý dữ liệu đầu vào và đầu ra cho bản đồ và để giảm bớt các hàm được biểu thị dưới dạng các cặp khóa-giá trị. Chúng phải tuân theo việc thực thi song song các tập dữ liệu nằm trong một loạt các máy trong một kiến trúc phân tán. Mô hình lập trình về bản chất là có chức năng trong việc kết hợp trong khi sử dụng kỹ thuật ánh xạ và rút gọn. Bài viết này giới thiệu mô hình MapReduce và đặc biệt, cách dữ liệu ở các định dạng khác nhau, từ văn bản đơn giản đến các đối tượng nhị phân có cấu trúc được sử dụng.
Các loại MapReduce
Lập bản đồ là kỹ thuật cốt lõi của việc xử lý danh sách các phần tử dữ liệu đi kèm với các cặp khóa và giá trị. Hàm bản đồ áp dụng cho các phần tử riêng lẻ được xác định là các cặp khóa-giá trị của một danh sách và tạo ra một danh sách mới. Ý tưởng chung về bản đồ và chức năng thu gọn của Hadoop có thể được minh họa như sau:
map: (K1, V1) -> list (K2, V2) reduce: (K2, list(V2)) -> list (K3, V3)
Các tham số đầu vào của cặp khóa và giá trị, được đại diện tương ứng bởi K1 và V1, khác với loại cặp đầu ra:K2 và V2. Hàm giảm chấp nhận cùng một định dạng đầu ra của bản đồ, nhưng loại đầu ra lại của hoạt động giảm là khác nhau:K3 và V3. API Java cho điều này như sau:
public interface Mapper<K1, V1, K2, V2> extends JobConfigurable, Closeable { void map(K1 key, V1 value, OutputCollector<K2, V2> output, Reporter reporter) throws IOException; } public interface Reducer<K2, V2, K3, V3> extends JobConfigurable, Closeable { void reduce(K2 key, Iterator<V2> values, OutputCollector<K3, V3> output, Reporter reporter)throws IOException; }
Bộ sưu tập đầu ra là giao diện tổng quát của khung Map-Reduce để tạo điều kiện thu thập dữ liệu đầu ra bởi Người lập bản đồ hoặc Hộp giảm tốc . Những đầu ra này không là gì ngoài đầu ra trung gian của công việc. Do đó, chúng phải được tham số hóa với các kiểu của chúng. The Reporter tạo điều kiện cho ứng dụng Map-Reduce báo cáo tiến độ và cập nhật các quầy và thông tin trạng thái. Tuy nhiên, nếu hàm kết hợp được sử dụng, nó có cùng dạng với hàm giảm và đầu ra được đưa vào hàm giảm. Điều này có thể được minh họa như sau:
map: (K1, V1) -> list (K2, V2) combine: (K2, list(V2)) -> list (K2, V2) reduce: (K2, list(V2)) -> list (K3, V3)
Lưu ý rằng các hàm kết hợp và hàm giảm sử dụng cùng một kiểu, ngoại trừ các tên biến trong đó K3 là K2 và V3 là V2.
Hàm phân vùng hoạt động trên các kiểu khóa-giá trị trung gian. Nó kiểm soát việc phân vùng các khóa của các đầu ra bản đồ trung gian. Khóa dẫn xuất phân vùng bằng cách sử dụng một hàm băm điển hình. Tổng số phân vùng giống như số tác vụ giảm bớt cho công việc. Phân vùng chỉ được xác định bởi khóa bỏ qua giá trị.
public interface Partitioner<K2, V2> extends JobConfigurable { int getPartition(K2 key, V2 value, int numberOfPartition); }
Tóm lại, đây là bản chất chính của các loại MapReduce.
Định dạng đầu vào
Hadoop phải chấp nhận và xử lý nhiều định dạng khác nhau, từ tệp văn bản đến cơ sở dữ liệu. Một đoạn dữ liệu đầu vào, được gọi là phân tách đầu vào , được xử lý bởi một bản đồ. Mỗi lần tách lại được chia thành các bản ghi logic được cung cấp cho bản đồ để xử lý theo cặp khóa-giá trị. Trong ngữ cảnh của cơ sở dữ liệu, sự phân tách có nghĩa là đọc một loạt các bộ giá trị từ một bảng SQL, như được thực hiện bởi DBInputFormat và sản xuất LongWritables chứa các số bản ghi làm khóa và DBWritables như các giá trị. API Java cho các phân tách đầu vào như sau:
public interface InputSplit extends Writable { long getLength() throws IOException; String[] getLocations() throws IOException; }
InputSplit đại diện cho dữ liệu sẽ được xử lý bởi một Người lập bản đồ . Nó trả về độ dài tính bằng byte và có tham chiếu đến dữ liệu đầu vào. Nó trình bày chế độ xem hướng byte trên đầu vào và là trách nhiệm của RecordReader của công việc để xử lý điều này và trình bày một dạng xem hướng đến bản ghi. Trong hầu hết các trường hợp, chúng tôi không xử lý InputSplit trực tiếp vì chúng được tạo bởi InputFormat . Đó là trách nhiệm của Định dạng đầu vào để tạo các phân tách đầu vào và chia chúng thành các bản ghi.
public interface InputFormat<K, V> { InputSplit[] getSplits(JobConf job, int numSplits) throws IOException; RecordReader<K, V> getRecordReader(InputSplit split, JobConf job, throws IOException; }
JobClient gọi ra getSplits () phương thức với số lượng đối số phân tách thích hợp. Con số đã cho là một gợi ý vì số lượng phân chia thực tế có thể khác với số lượng đã cho. Sau khi tính toán sự phân chia, nó sẽ được gửi đến trình theo dõi công việc. Trình theo dõi công việc lên lịch các tác vụ ánh xạ cho trình theo dõi tác vụ bằng cách sử dụng vị trí lưu trữ. Sau đó, trình theo dõi tác vụ vượt qua sự phân tách bằng cách gọi getRecordReader () trên InputFormat để tải RecordReader cho sự phân chia.
FileInputFormat là lớp cơ sở cho nguồn dữ liệu tệp. Nó có trách nhiệm xác định các tệp sẽ được đưa vào làm đầu vào công việc và định nghĩa để tạo phân tách.
Hadoop cũng bao gồm xử lý dữ liệu phi cấu trúc thường có định dạng văn bản. TextInputFormat là InputFormat mặc định cho dữ liệu đó.
SequenceInputFormat nhận đầu vào nhị phân và lưu trữ chuỗi các cặp khóa-giá trị nhị phân.
Tương tự, DBInputFormat cung cấp khả năng đọc dữ liệu từ cơ sở dữ liệu quan hệ bằng JDBC.
Định dạng đầu ra
Các lớp định dạng đầu ra tương tự như các lớp định dạng đầu vào tương ứng của chúng và hoạt động theo hướng ngược lại.
Ví dụ: TextOutputFormat là định dạng đầu ra mặc định ghi các bản ghi dưới dạng tệp văn bản thuần túy, trong khi khóa-giá trị bất kỳ thuộc bất kỳ loại nào và chuyển đổi chúng thành một chuỗi bằng cách gọi toString () phương pháp. Ký tự khóa-giá trị được phân tách bằng ký tự tab, mặc dù điều này có thể được tùy chỉnh bằng cách thao tác với thuộc tính dấu phân cách của định dạng đầu ra văn bản.
Đối với đầu ra nhị phân, có SequenceFileOutputFormat để ghi một chuỗi đầu ra nhị phân vào một tệp. Đầu ra nhị phân đặc biệt hữu ích nếu đầu ra trở thành đầu vào cho một công việc MapReduce khác.
Định dạng đầu ra cho cơ sở dữ liệu quan hệ và HBase được xử lý bởi DBOutputFormat . Nó gửi đầu ra đã giảm tới một bảng SQL. Ví dụ: TableOutputFormat của HBase cho phép chương trình MapReduce hoạt động trên dữ liệu được lưu trữ trong bảng HBase và sử dụng nó để ghi kết quả đầu ra vào bảng HBase.
Kết luận
Tóm lại, đây là mấu chốt của các loại và định dạng MapReduce. Tham khảo danh sách trong tài liệu tham khảo dưới đây để biết thêm chi tiết về chúng. Có nhiều chi tiết phức tạp về các chức năng của các API Java chỉ trở nên rõ ràng hơn khi người ta đi sâu vào lập trình. Tham khảo tài liệu Apache Hadoop Java API để biết thêm chi tiết và bắt đầu viết một số phương pháp.
Tài liệu tham khảo
- Tom White, Hadoop Hướng dẫn Cuối cùng , O’Reilly
- Tài liệu Java API Apache Hadoop