1. Trang chủ
  2. » Công Nghệ Thông Tin

Xử lý dữ liệu phân tán bằng Hadoop, Phần 3: Phát triển ứng dụng ppsx

18 615 2

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 18
Dung lượng 3,8 MB

Nội dung

Bài viết cuối cùng trong loạt bài này tìm hiểu các API Giao diện lập trình ứng dụng của Hadoop và luồng dữ liệu và trình bày cách sử dụng của chúng với một ứng dụng trình ánh xạ mapper v

Trang 1

Xử lý dữ liệu phân tán bằng Hadoop, Phần 3: Phát triển ứng dụng

Phát triển một ứng dụng MapReduce của Ruby cho Hadoop

M Tim Jones, Tác giả độc lập, Emulex

Tóm tắt: Với việc cấu hình, cài đặt và sử dụng Hadoop trong các kiến trúc một

nút và nhiều nút đã thu được, bạn có thể chuyển sang nhiệm vụ phát triển các ứng dụng trong cơ sở hạ tầng Hadoop Bài viết cuối cùng trong loạt bài này tìm hiểu các API (Giao diện lập trình ứng dụng) của Hadoop và luồng dữ liệu và trình bày cách sử dụng của chúng với một ứng dụng trình ánh xạ (mapper) và trình rút gọn (reducer) đơn giản

Hai bài viết đầu tiên của loạt bài này tập trung vào việc cài đặt và cấu hình của Hadoop cho các cụm đơn nút và đa nút Bài viết cuối cùng này tìm hiểu cách lập trình trong Hadoop—nói cụ thể là sự phát triển của ứng dụng ánh xạ và rút gọn trong ngôn ngữ Ruby Tôi chọn Ruby, vì thứ nhất, nó là một ngôn ngữ tạo kịch bản lệnh hướng đối tượng tuyệt vời mà bạn nên biết và thứ hai bạn sẽ tìm thấy nhiều tài liệu tham khảo trong phần Tài nguyên với các hướng dẫn tập trung vào

cả ngôn ngữ Java™ lẫn ngôn ngữ Python Qua việc tìm hiểu này về lập trình

MapReduce, tôi cũng giới thiệu cho bạn về API theo luồng API này cung cấp phương tiện để phát triển các ứng dụng trên các ngôn ngữ khác với ngôn ngữ Java

Hãy bắt đầu bằng một giới thiệu ngắn về ánh xạ và rút gọn (theo quan điểm chức năng) và sau đó đi sâu vào mô hình lập trình Hadoop và kiến trúc của nó và các yếu tố dùng để chia cắt, phân phối và quản lý công việc

Nguồn gốc ánh xạ và rút gọn

Vì vậy, cái gì là các yếu tố chức năng đã thôi thúc mô hình lập trình MapReduce?

Vào năm 1958, John McCarthy đã phát minh ra một ngôn ngữ gọi là Lisp, cho

phép triển khai thực hiện cả tính toán số lẫn tính toán ký hiệu nhưng dưới dạng đệ quy xa lạ với hầu hết các ngôn ngữ đang sử dụng hiện nay (Thực sự có một lịch

sử hấp dẫn về Lisp trên Wikipedia bao gồm một hướng dẫn thực tế — đáng bỏ thời gian để đọc) Lisp lần đầu tiên được thực hiện trên máy IBM® 704, máy tính được sản xuất hàng loạt đầu tiên cũng hỗ trợ cho ngôn ngữ đã quen thuộc từ trước được yêu thích là: FORTRAN

Hàm map (ánh xạ) có nguồn gốc trong các ngôn ngữ chức năng như Lisp nhưng bây giờ đã phổ biến trong nhiều ngôn ngữ khác, là một ứng dụng hàm số trên một danh sách các phần tử Điều này có nghĩa gì? Liệt kê 1 cung cấp một phiên giao dịch với Scheme Shell (SCSH), đó là dẫn xuất của Lisp Dòng đầu tiên xác định

Trang 2

một hàm được gọi là square (bình phương) nhận một đối số và trả về căn bậc hai của nó Dòng tiếp theo minh họa việc sử dụng hàm map Như đã thấy, với hàm map, bạn cung cấp hàm của mình và danh sách các phần tử mà hàm này được áp dụng Kết quả là một danh sách mới có chứa các phần tử bình phương

Liệt kê 1 Biểu diễn hàm map trong SCSH

> (define square (lambda (x) (* x x)))

> (map square '(1 3 5 7))

'(1 9 25 49)

>

Việc rút gọn cũng được áp dụng trên một danh sách nhưng thường rút gọn danh sách theo một giá trị vô hướng Ví dụ có trong Liệt kê 2 minh họa một hàm SCSH khác để thu nhỏ một danh sách theo một dạng vô hướng—trong trường hợp này, tổng hợp danh sách các giá trị theo dạng (1 + (2 + (3 + (4 + (5))))) Lưu ý rằng đây

là cách lập trình chức năng cổ điển, dựa vào phép đệ quy qua phép lặp

Liệt kê 2 Biểu diễn hàm rút gọn trong SCSH

> (define (list-sum lis) (if (null? lis) 0 (+ (car lis) (list-sum (cdr lis)))))

> (list-sum '(1 2 3 4 5))

15

>

Trang 3

Thật thú vị khi nhận thấy rằng phép đệ quy là phép lặp hiệu quả trong các ngôn ngữ mệnh lệnh vì phép đệ quy được dịch thành phép lặp trong các bao gói

Mô hình lập trình của Hadoop

Google đã giới thiệu ý tưởng về MapReduce như là một mô hình lập trình để xử lý hay tạo các tập dữ liệu lớn Trong mô hình chính tắc, một hàm map xử lý các cặp giá trị-khóa, tạo ra một tập trung gian của các cặp giá trị-khóa Sau đó hàm reduce

xử lý các cặp giá trị-khóa trung gian đó, kết hợp các giá trị với các khóa có liên quan (xem Hình 1) Dữ liệu đầu vào được phân chia thành nhiều phần theo cách

để cho nó có thể được phân phối trong một cụm các máy cho phép xử lý song song Theo cách như vậy, dữ liệu trung gian đã tạo ra được xử lý song song, làm cho cách tiếp cận này là lý tưởng đối với việc xử lý số lượng dữ liệu rất lớn

Hình 1 Hình ảnh đơn giản hóa của quá trình xử lý MapReduce

Với một trình làm mới nhanh chóng, hãy xem xét các kiến trúc từ Hình 1 theo quan điểm về ánh xạ và rút gọn cho việc đếm từ (vì bạn sẽ phát triển một ứng dụng ánh xạ và rút gọn trong bài viết này) Khi dữ liệu đầu vào được cung cấp (vào trong hệ thống tệp của Hadoop [HDFS]), đầu tiên nó được chia thành các phần và sau đó được phân phối tới các trình công việc (worker) ánh xạ (thông qua

Trang 4

trình theo dõi công việc) Mặc dù ví dụ trong Hình 2 cho thấy một câu ngắn được chia nhỏ, thông thường số từ để chia nhỏ thành dải có kích thước khoảng 128MB

vì lý do là: Cần rất ít thời gian để thiết lập công việc, vì có nhiều việc để làm nên cần giảm thiểu chi phí hoạt động này Các trình công việc ánh xạ (trong ví dụ chính tắc) phân chia công việc thành các vectơ riêng có chứa các từ được đánh dấu

và giá trị ban đầu (là 1, trong trường hợp này) Khi hoàn thành các nhiệm vụ ánh

xạ (do trình theo dõi công việc - task tracker trong Hadoop quy định), công việc này được chuyển tới trình công việc rút gọn Trình công việc rút gọn biến đổi các khóa thành một tập duy nhất, có giá trị biểu diễn số lượng các khóa đã tìm thấy

Hình 2 Ví dụ MapReduce đơn giản

Trang 5

Lưu ý rằng quá trình này có thể xảy ra trên cùng một máy hoặc các máy khác nhau hoặc được thực hiện tuần tự hoặc song song nhờ sử dụng cách phân vùng dữ liệu khác nhau và vẫn cho kết quả như nhau

Mặc dù quan điểm chính tắc (cho việc tìm kiếm tạo chỉ mục bằng cách sử dụng đếm từ) là một cách để xem xét Hadoop, nó cho thấy rằng mô hình điện toán này

có thể được áp dụng chung cho một số vấn đề tính toán, như bạn sẽ thấy

Tính linh hoạt của Hadoop

Từ ví dụ đơn giản chỉ ra trong Hình 2, lưu ý rằng hai phần tử chính là các quá trình map và reduce Mặc dù có quan điểm truyền thống về cách hoạt động của quá trình này, nhưng đó không phải là một yêu cầu về kiến trúc cho các quá trình map

và reduce để chạy theo cách này Đây là sức mạnh thực sự của Hadoop — tính linh hoạt của nó để triển khai thực hiện các quá trình map và reduce để vận hành theo cách giải quyết một ứng dụng cụ thể Ví dụ đếm từ là có ích và có thể áp dụng cho một số lượng các vấn đề lớn, nhưng các mô hình khác vẫn còn thích hợp trong khung công tác chung này Tất cả những thứ cần thiết là sự phát triển của ứng dụng map và reduce để tạo ra các quá trình hiển thị cho Hadoop

Trong số các ứng dụng khác, Hadoop thậm chí đã được sử dụng cho các ứng dụng học máy với các thuật toán đa dạng như các mạng thần kinh, các máy vector tựa

và phân cụm theo thuật toán k-means (xem phần Tài nguyên để biết thêm thông

tin)

Tạo luồng dữ liệu

Mặc dù Hadoop là một khung công tác dựa trên Java, nhưng lại có thể viết các ứng dụng map và reduce bằng các ngôn ngữ khác ngôn ngữ Java Việc tạo luồng đáp ứng điều này Tiện ích streaming (tạo luồng) trong Hadoop thực hiện một kiểu kết nối luồng dữ liệu Với tiện ích streaming, bạn có thể xác định các khả năng thực thi ánh xạ và rút gọn riêng của bạn (với mỗi đầu vào lấy từ đầu vào tiêu chuẩn [stdin] và đưa ra kết quả qua đầu ra chuẩn [stdout]) và tiện ích streaming đọc và ghi dữ liệu một cách thích hợp, gọi ra các ứng dụng của bạn khi cần (xem Liệt kê 3)

Trang 6

Liệt kê 3 Sử dụng tiện ích streaming của Hadoop

hadoop jar $HADOOP_HOME/hadoop-streaming.jar \

-input inputData

-output outputData

-mapper map_exec

-reducer reduce_exec

Liệt kê 3 minh họa cách sử dụng tiện ích streaming trong Hadoop, trong khi Hình

3 cho thấy bằng biểu đồ cách xác định luồng dữ liệu Lưu ý rằng đây là một ví dụ đơn giản về sử dụng tạo luồng Có sẵn nhiều tùy chọn để điều chỉnh cách phân tích

cú pháp dữ liệu, để điều chỉnh cách lấy các hình ảnh, để xác định hình ảnh thay thế cho bộ phân vùng hoặc bộ kết hợp và chỉnh sửa cấu hình khác (xem phần Tài nguyên để biết thêm thông tin)

Hình 3 Ví dụ tạo luồng đồ họa

Trang 7

Ví dụ về Ruby

Với hiểu biết cơ bản về tiện ích streaming đã thu được, bạn đã sẵn sàng viết một ứng dụng ánh xạ và rút gọn Ruby đơn giản và xem cách sử dụng các quá trình này trong khung công tác Hadoop Ví dụ ở đây theo ứng dụng MapReduce chính tắc, nhưng vè sau bạn sẽ thấy các ứng dụng khác (cùng với cách bạn sẽ triển khai thực hiện chúng dưới dạng ánh xạ và rút gọn)

Hãy bắt đầu bằng trình ánh xạ (mapper) Kịch bản lệnh này nhận đầu vào nguyên bản từ stdin (đầu vào chuẩn), đánh dấu nó và rồi phát hành một tập hợp các cặp giá trị-khóa tới stdout (đầu ra chuẩn) Giống như hầu hết các ngôn ngữ tạo kịch bản lệnh hướng-đối tượng, nhiệm vụ này hầu như quá đơn giản Kịch bản lệnh của trình ánh xạ thể hiện trong Liệt kê 4 (với một số nhận xét và khoảng trống để cho

nó có kích thước lớn hơn một chút) Chương trình này sử dụng một trình lặp (iterator) để đọc một dòng từ stdin và một trình lặp khác để phân chia dòng đó thành các mã thông báo riêng Mỗi mã đánh dấu (từ) lúc này được phát hành tới stdout với giá trị đi kèm là 1 (được phân cách nhờ một tab)

Liệt kê 4 Kịch bản lệnh ánh xạ của Ruby (map.rb)

#!/usr/bin/env ruby

# Our input comes from STDIN

STDIN.each_line do |line|

# Iterate over the line, splitting the words from the line and emitting

# as the word with a count of 1

line.split.each do |word|

Trang 8

puts "#{word}\t1"

end

end

Tiếp theo, hãy xem xét ứng dụng rút gọn Ứng dụng này phức tạp hơn một chút nhưng sử dụng một hàm băm (mảng kết hợp) của Ruby để đơn giản hóa hoạt động rút gọn (xem Liệt kê 5) Kịch bản lệnh này một lần nữa hoạt động thông qua dữ liệu đầu vào từ stdin (thông qua tiện ích streaming) và chia dòng đó thành một từ

và giá trị Hàm băm này sau đó được kiểm tra với từ này; nếu tìm thấy từ, thì số đếm được thêm vào phần tử Nếu không, bạn tạo một mục nhập mới trong hàm băm cho từ đó và rồi nạp số đếm (mà phải là 1 từ quá trình của trình ánh xạ) Khi tất cả đầu vào đã được xử lý, bạn chỉ lặp lại qua hàm băm và gửi các cặp giá tri-khóa tới stdout

Liệt kê 5 Kịch bản lệnh rút gọn của Ruby (reduce.rb)

#!/usr/bin/env ruby

# Create an empty word hash

wordhash = {}

# Our input comes from STDIN, operating on each line

STDIN.each_line do |line|

Trang 9

# Each line will represent a word and count

word, count = line.strip.split

# If we have the word in the hash, add the count to it, otherwise

# create a new one

if wordhash.has_key?(word)

wordhash[word] += count.to_i

else

wordhash[word] = count.to_i

end

end

# Iterate through and emit the word counters

wordhash.each {|record, count| puts "#{record}\t#{count}"}

Với các kịch bản lệnh ánh xạ và rút gọn đã hoàn thành, hãy kiểm tra chúng từ dòng lệnh Hãy nhớ thay đổi các tệp này để có thể thực hiện được bằng cách sử dụng chmod +x Bắt đầu bằng cách tạo ra một tệp đầu vào, như trong Liệt kê 6

Liệt kê 6 Tạo một tệp đầu vào

Trang 10

# echo "Hadoop is an implementation of the map reduce framework for " \ "distributed processing of large data sets." > input

#

Với đầu vào này, bạn có thể kiểm tra kịch bản lệnh của trình ánh xạ của bạn, như trong Liệt kê 7 Hãy nhớ lại rằng kịch bản lệnh này chỉ đơn giản gắn mã cho đầu vào đến các cặp giá trị-khóa, ở đây mỗi giá trị sẽ là 1 (không phải đầu vào duy nhất)

Liệt kê 7 Kiểm tra kịch bản lệnh của trình ánh xạ

# cat input | ruby map.rb

Hadoop 1

is 1

an 1

implementation 1

of 1

the 1

map 1

reduce 1

framework 1

for 1

distributed 1

Trang 11

processing 1

of 1

large 1

data 1

sets 1

#

Cho đến nay, mọi thứ đều ổn Bây giờ, hãy kết hợp toàn bộ ứng dụng với nhau dưới dạng tạo luồng gốc (các đường ống của (Linux®) Trong Liệt kê 8, bạn chuyển đầu vào của mình qua kịch bản lệnh ánh xạ của mình, sắp xếp kết quả đầu

ra (bước tùy chọn) và sau đó chuyển dữ liệu kết quả trung gian qua kịch bản lệnh của trình rút gọn

Liệt kê 8 Quá trình MapReduce đơn giản khi sử dụng các đường ống của Linux

# cat input | ruby map.rb | sort | ruby reduce.rb

large 1

of 2

framework 1

distributed 1

data 1

an 1

the 1

Trang 12

reduce 1

map 1

sets 1

Hadoop 1

implementation 1

for 1

processing 1

is 1

#

Ruby với Hadoop

Khi các kịch bản lệnh ánh xạ và rút gọn của bạn hoạt động như mong muốn trong môi trường shell, hãy đặt chúng vào để thử nghiệm với Hadoop Tôi sẽ bỏ qua các nhiệm vụ thiết lập Hadoop (xem Phần 1 hoặc Phần 2 của loạt bài này để cài đặt Hadoop và chạy)

Bước đầu tiên là tạo một thư mục đầu vào trong HDFS cho dữ liệu đầu vào của bạn và sau đó đưa ra một tệp mẫu mà bạn sẽ thử nghiệm các kịch bản của mình trong đó Liệt kê 9 minh họa bước này (xem Phần 1 hoặc Phần 2 để biết thêm thông tin về các bước này)

Liệt kê 9 Tạo dữ liệu đầu vào cho quá trình MapReduce

Trang 13

# hadoop fs -mkdir input

# hadoop dfs -put

/usr/src/linux-source-2.6.27/Documentation/memory-barriers.txt input

# hadoop fs -ls input

Found 1 items

-rw-r r 1 root supergroup 78031 2010-06-04 17:36 /user/root/input/memory-barriers.txt

#

Tiếp theo, sử dụng tiện ích streaming gọi Hadoop với các kịch bản lệnh tùy chỉnh, xác định dữ liệu đầu vào và vị trí đầu ra (xem Liệt kê 10) Lưu ý trong ví dụ này các tùy chọn -file chỉ đơn giản là ra lệnh cho Hadoop đóng gói các kịch bản lệnh Ruby của bạn như là một phần đệ trình công việc

Liệt kê 10 Sử dụng tạo luồng của Hadoop với các kịch bản lệnh tùy chỉnh MapReduce của Ruby

# hadoop jar /usr/lib/hadoop-0.20/contrib/streaming/hadoop-0.20.2+228-streaming.jar \

-file /home/mtj/ruby/map.rb -mapper /home/mtj/ruby/map.rb \

-file /home/mtj/ruby/reduce.rb -reducer /home/mtj/ruby/reduce.rb \ -input input/* -output output

packageJobJar: [/home/mtj/ruby/map.rb, /home/mtj/ruby/reduce.rb,

/var/lib/hadoop-0.20/

10/06/04 17:42:38 INFO mapred.FileInputFormat: Total input paths to process : 1 10/06/04 17:42:39 INFO streaming.StreamJob: getLocalDirs():

Trang 14

[/var/lib/hadoop-0.20/

10/06/04 17:42:39 INFO streaming.StreamJob: Running job:

job_201006041053_0001

10/06/04 17:42:39 INFO streaming.StreamJob: To kill this job, run:

10/06/04 17:42:39 INFO streaming.StreamJob: /usr/lib/hadoop-0.20/bin/hadoop job

10/06/04 17:42:39 INFO streaming.StreamJob: Tracking URL:

http://localhost:50030/

10/06/04 17:42:40 INFO streaming.StreamJob: map 0% reduce 0%

10/06/04 17:43:17 INFO streaming.StreamJob: map 100% reduce 0%

10/06/04 17:43:26 INFO streaming.StreamJob: map 100% reduce 100%

10/06/04 17:43:29 INFO streaming.StreamJob: Job complete:

job_201006041053_0001

10/06/04 17:43:29 INFO streaming.StreamJob: Output: output

#

Cuối cùng, tìm hiểu kết quả đầu ra bằng cách sử dụng phép toán của hệ thống tệp cat thông qua tiện ích hadoop (xem Liệt kê 11)

Liệt kê 11 Tìm hiểu kết quả đầu ra của Hadoop

# hadoop fs -ls /user/root/output

Found 2 items

drwxr-xr-x - root supergroup 0 2010-06-04 17:42 /user/root/output/_logs

Ngày đăng: 07/08/2014, 10:22

HÌNH ẢNH LIÊN QUAN

Hình 1. Hình ảnh đơn giản hóa của quá trình xử lý MapReduce - Xử lý dữ liệu phân tán bằng Hadoop, Phần 3: Phát triển ứng dụng ppsx
Hình 1. Hình ảnh đơn giản hóa của quá trình xử lý MapReduce (Trang 3)
Hình 2. Ví dụ MapReduce đơn giản - Xử lý dữ liệu phân tán bằng Hadoop, Phần 3: Phát triển ứng dụng ppsx
Hình 2. Ví dụ MapReduce đơn giản (Trang 4)
Hình 3. Ví dụ tạo luồng đồ họa - Xử lý dữ liệu phân tán bằng Hadoop, Phần 3: Phát triển ứng dụng ppsx
Hình 3. Ví dụ tạo luồng đồ họa (Trang 6)

TỪ KHÓA LIÊN QUAN

TÀI LIỆU CÙNG NGƯỜI DÙNG

TÀI LIỆU LIÊN QUAN

w