Thứ Ba, 3 tháng 9, 2013

Giới thiệu ngắn về HDFS và MapReduce


Trước khi bạn bắt đầu di chuyển dữ liệu giữa cơ sở dữ liệu quan hệ của bạn và Hadoop, bạn cần biết qua về HDFS và MapReduce. Có rất nhiều hướng dẫn kiểu "hello world" cho Hadoop, vì thế các ví dụ ở đây được đưa ra chỉ nhằm để cung cấp đủ thông tin cơ bản để bạn hiểu các bài tập thực hành cơ sở dữ liệu của mình.
HDFS cung cấp lưu trữ trên các nút trong cụm của bạn. Bước đầu tiên trong việc sử dụng Hadoop là đưa dữ liệu vào HDFS. Mã được hiển thị trong Liệt kê 3 lấy một bản sao của một cuốn sách của Mark Twain và một cuốn sách của James Fenimore Cooper và sao chép các văn bản này vào HDFS.

Liệt kê 3. Nạp văn bản cuốn sách của Mark Twain và của James Fenimore Cooper vào HDFS
                 
# install wget utility into the virtual image
sudo yum install wget
                
# use wget to download the Twain and Cooper's works
$ wget -U firefox http://www.gutenberg.org/cache/epub/76/pg76.txt
$ wget -U firefox http://www.gutenberg.org/cache/epub/3285/pg3285.txt
                
# load both into the HDFS file system
# first give the files better names
# DS for Deerslayer
# HF for  Huckleberry Finn
$ mv pg3285.txt DS.txt
$ mv pg76.txt HF.txt
                
# this next command will fail if the directory already exists
$ hadoop fs -mkdir /user/cloudera 
                
# now put the text into the directory 
$ hadoop fs -put HF.txt /user/cloudera
                
                
# way too much typing, create aliases for hadoop commands
$ alias hput="hadoop fs -put"
$ alias hcat="hadoop fs -cat"
$ alias hls="hadoop fs -ls"
# for CDH4 
$ alias hrmr="hadoop fs -rm -r"
# for CDH3 
$ alias hrmr="hadoop fs -rmr"
                
# load the other article
# but add some compression because we can 
                
$ gzip DS.txt 
                
# the  .  in the next command references the cloudera home directory
# in hdfs, /user/cloudera 
                
$ hput DS.txt.gz .
                
# now take a look at the files we have in place
$ hls
Found 2 items
-rw-r--r-- 1 cloudera supergroup  459386 2012-08-08 19:34 /user/cloudera/DS.txt.gz
-rw-r--r-- 1 cloudera supergroup  597587 2012-08-08 19:35 /user/cloudera/HF.txt           
            

Bây giờ bạn có hai tệp trong một thư mục trong HDFS. Đừng phấn khích vội. Thật tình, trên một nút duy nhất và với chỉ có khoảng 1 megabyte, chả có gì đáng xem. Nhưng nếu đây là một cụm có 400 nút và bạn có 5 petabyte đang tồn tại, thì bạn sẽ thực sự rất khó kìm giữ sự hứng thú của mình.
Nhiều hướng dẫn trong số các hướng dẫn Hadoop sử dụng ví dụ đếm từ đã có trong tệp jar ví dụ. Hóa ra là rất nhiều phân tích liên quan đến việc đếm và gộp. Ví dụ trong Liệt kê 4 giới thiệu cho bạn cách gọi bộ đếm từ.

Liệt kê 4. Đếm các từ trong tác phẩm của Twain và Cooper
                 
# hadoop comes with some examples
# this next line uses the provided java implementation of a 
# word count program
                
# for CDH4:
hadoop jar /usr/lib/hadoop-0.20-mapreduce/hadoop-examples.jar wordcount HF.txt HF.out

# for CDH3:
hadoop jar /usr/lib/hadoop/hadoop-examples.jar wordcount HF.txt HF.out
                
# for CDH4:
hadoop jar /usr/lib/hadoop-0.20-mapreduce/hadoop-examples.jar wordcount DS.txt.gz DS.out

# for CDH3:
hadoop jar /usr/lib/hadoop/hadoop-examples.jar wordcount  DS.txt.gz DS.out
            

Hậu tố .gz trong tệp DS.txt.gz nói cho Hadoop biết xử lý giải nén như là một phần của việc xử lý Map-Reduce. Cooper hơi dài dòng một chút vì thế đáng nén nó.
Còn có một luồng các thông báo từ việc chạy công việc đếm từ của bạn. Hadoop rất vui lòng cung cấp nhiều chi tiết về các chương trình Mapping và Reducing đang chạy thay cho bạn. Các dòng quan trọng mà bạn muốn tìm xem được hiển thị trong Liệt kê 5, bao gồm cả một liệt kê thứ hai về công việc có lỗi và cách sửa chữa một trong những lỗi phổ biến nhất mà bạn sẽ gặp phải khi chạy MapReduce.

Liệt kê 5. Các thông báo MapReduce - "con đường hạnh phúc"
                 
$ hadoop jar /usr/lib/hadoop/hadoop-examples.jar wordcount HF.txt HF.out
12/08/08 19:23:46 INFO input.FileInputFormat: Total input paths to process : 1
12/08/08 19:23:47 WARN snappy.LoadSnappy: Snappy native library is available
12/08/08 19:23:47 INFO util.NativeCodeLoader: Loaded the native-hadoop library
12/08/08 19:23:47 INFO snappy.LoadSnappy: Snappy native library loaded
12/08/08 19:23:47 INFO mapred.JobClient: Running job: job_201208081900_0002
12/08/08 19:23:48 INFO mapred.JobClient:  map 0% reduce 0%
12/08/08 19:23:54 INFO mapred.JobClient:  map 100% reduce 0%
12/08/08 19:24:01 INFO mapred.JobClient:  map 100% reduce 33%
12/08/08 19:24:03 INFO mapred.JobClient:  map 100% reduce 100%
12/08/08 19:24:04 INFO mapred.JobClient: Job complete: job_201208081900_0002
12/08/08 19:24:04 INFO mapred.JobClient: Counters: 26
12/08/08 19:24:04 INFO mapred.JobClient:   Job Counters 
12/08/08 19:24:04 INFO mapred.JobClient:     Launched reduce tasks=1
12/08/08 19:24:04 INFO mapred.JobClient:     SLOTS_MILLIS_MAPS=5959
12/08/08 19:24:04 INFO mapred.JobClient:     Total time spent by all reduces...
12/08/08 19:24:04 INFO mapred.JobClient:     Total time spent by all maps waiting...
12/08/08 19:24:04 INFO mapred.JobClient:     Launched map tasks=1
12/08/08 19:24:04 INFO mapred.JobClient:     Data-local map tasks=1
12/08/08 19:24:04 INFO mapred.JobClient:     SLOTS_MILLIS_REDUCES=9433
12/08/08 19:24:04 INFO mapred.JobClient:   FileSystemCounters
12/08/08 19:24:04 INFO mapred.JobClient:     FILE_BYTES_READ=192298
12/08/08 19:24:04 INFO mapred.JobClient:     HDFS_BYTES_READ=597700
12/08/08 19:24:04 INFO mapred.JobClient:     FILE_BYTES_WRITTEN=498740
12/08/08 19:24:04 INFO mapred.JobClient:     HDFS_BYTES_WRITTEN=138218
12/08/08 19:24:04 INFO mapred.JobClient:   Map-Reduce Framework
12/08/08 19:24:04 INFO mapred.JobClient:     Map input records=11733
12/08/08 19:24:04 INFO mapred.JobClient:     Reduce shuffle bytes=192298
12/08/08 19:24:04 INFO mapred.JobClient:     Spilled Records=27676
12/08/08 19:24:04 INFO mapred.JobClient:     Map output bytes=1033012
12/08/08 19:24:04 INFO mapred.JobClient:     CPU time spent (ms)=2430
12/08/08 19:24:04 INFO mapred.JobClient:     Total committed heap usage (bytes)=183701504
12/08/08 19:24:04 INFO mapred.JobClient:     Combine input records=113365
12/08/08 19:24:04 INFO mapred.JobClient:     SPLIT_RAW_BYTES=113
12/08/08 19:24:04 INFO mapred.JobClient:     Reduce input records=13838
12/08/08 19:24:04 INFO mapred.JobClient:     Reduce input groups=13838
12/08/08 19:24:04 INFO mapred.JobClient:     Combine output records=13838
12/08/08 19:24:04 INFO mapred.JobClient:     Physical memory (bytes) snapshot=256479232
12/08/08 19:24:04 INFO mapred.JobClient:     Reduce output records=13838
12/08/08 19:24:04 INFO mapred.JobClient:     Virtual memory (bytes) snapshot=1027047424
12/08/08 19:24:04 INFO mapred.JobClient:     Map output records=113365
            

Tất cả các thông báo trên có ý nghĩa gì? Hadoop đã thực hiện nhiều công việc và đang cố gắng báo cho bạn biết về chúng, bao gồm những việc sau:
  • Đã kiểm tra để xem liệu các tệp đầu vào có tồn tại không.
  • Đã kiểm tra để xem liệu thư mục đầu ra đã tồn tại chưa, và nếu có, thì hủy bỏ công việc. Không gì tệ hơn là ghi đè lên hàng giờ tính toán, chỉ bởi một lỗi bàn phím đơn giản.
  • Đã phân phối tệp jar của Java cho tất cả các nút chịu trách nhiệm thực hiện công việc này. Trong trường hợp này, chỉ có một nút duy nhất.
  • Đã chạy giai đoạn ánh xạ của công việc. Thông thường giai đoạn này phân tích cú pháp tệp đầu vào và phát ra một cặp khóa giá trị. Lưu ý khóa và giá trị có thể là các đối tượng.
  • Đã chạy giai đoạn sắp xếp để sắp xếp các kết quả đầu ra của trình ánh xạ dựa trên khóa.
  • Đã chạy giai đoạn rút gọn, thường giai đoạn này tóm lược luồng key-value và ghi kết quả đầu ra vào HDFS.
  • Đã tạo các số liệu đo lường trong tiến trình.
Hình 6 cho thấy một trang web ví dụ mẫu về các số liệu đo lường của công việc Hadoop sau khi chạy bài tập thực hành Hive.

Hình 6. Trang web ví dụ mẫu của Hadoop
Hình này hiển thị trang web ví dụ mẫu về các số liệu đo lường của công việc Hadoop                     sau khi chạy bài thực hành Hive
Công việc này đã làm gì và kết quả đầu ra nằm ở đâu? Cả hai đều là những câu hỏi thích hợp và được hiển thị trong Liệt kê 6.

Liệt kê 6. Kết quả đầu ra của Map-Reduce
                        
# way too much typing, create aliases for hadoop commands
$ alias hput="hadoop fs -put"
$ alias hcat="hadoop fs -cat"
$ alias hls="hadoop fs -ls"
$ alias hrmr="hadoop fs -rmr"
                
# first list the output directory
$ hls /user/cloudera/HF.out
Found 3 items
-rw-r--r-- 1 cloudera supergroup 0 2012-08-08 19:38 /user/cloudera/HF.out/_SUCCESS
drwxr-xr-x - cloudera supergroup 0 2012-08-08 19:38 /user/cloudera/HF.out/_logs
-rw-r--r-- 1 cl... sup... 138218 2012-08-08 19:38 /user/cloudera/HF.out/part-r-00000
                
# now cat the file and pipe it to  the  less command
$ hcat /user/cloudera/HF.out/part-r-00000 | less
                
# here are a few lines from the file, the word elephants only got used twice
elder,  1
eldest  1
elect   1
elected 1
electronic      27
electronically  1
electronically, 1
elegant 1
elegant!--'deed 1
elegant,        1
elephants       2
            

Trong trường hợp bạn chạy cùng một công việc hai lần và quên xóa thư mục kết quả đầu ra, bạn sẽ nhận được các thông báo lỗi được hiển thị trong Liệt kê 7. Việc sửa lỗi này chỉ đơn giản là xóa thư mục đó.

Liệt kê 7. Các thông báo MapReduce – lỗi do kết quả đầu ra đã tồn tại trong HDFS
                 
# way too much typing, create aliases for hadoop commands
$ alias hput="hadoop fs -put"
$ alias hcat="hadoop fs -cat"
$ alias hls="hadoop fs -ls"
$ alias hrmr="hadoop fs -rmr"               
                
$ hadoop jar /usr/lib/hadoop/hadoop-examples.jar wordcount HF.txt HF.out
12/08/08 19:26:23 INFO mapred.JobClient: 
Cleaning up the staging area hdfs://0.0.0.0/var/l...
12/08/08 19:26:23 ERROR security.UserGroupInformation: PriviledgedActionException 
as:cloudera (auth:SIMPLE) 
cause:org.apache.hadoop.mapred.FileAlreadyExistsException: 
Output directory HF.out already exists
org.apache.hadoop.mapred.FileAlreadyExistsException: 
Output directory HF.out already exists
at org.apache.hadoop.mapreduce.lib.output.FileOutputFormat.
checkOutputSpecs(FileOutputFormat.java:132)
at org.apache.hadoop.mapred.JobClient$2.run(JobClient.java:872)
at org.apache.hadoop.mapred.JobClient$2.run(JobClient.java:833)
                
.... lines deleted
                
# the simple fix is to remove the existing output directory
                
$ hrmr HF.out
                
# now you can re-run the job successfully
                
# if you run short of space and the namenode enters safemode
# clean up some file space and then
                
$ hadoop dfsadmin -safemode leave
            

Hadoop có một giao diện trình duyệt để kiểm tra trạng thái của HDFS. Hình 7 cho thấy kết quả đầu ra của công việc đếm từ.

Hình 7. Khám phá HDFS bằng một trình duyệt
Hình này hiển thị việc khám phá HDFS bằng một trình duyệt
Một giao diện điều khiển tinh tế hơn có sẵn miễn phí trong trang web của Cloudera. Nó cung cấp một số khả năng nằm ngoài các giao diện web Hadoop chuẩn. Lưu ý rằng tình trạng sức khỏe của HDFS trong Hình 8 được hiển thị là Bad (Kém).

Hình 8. Trình quản lý Cloudera quản lý Các dịch vụ Hadoop
Hình này hiển thị Trình quản lý Cloudera quản lý Hadoop Services
Tại sao tình trạng sức khỏe của HDFS lại kém? Vì trong một máy ảo đơn, HDFS không thể tạo ra ba bản sao của các khối dữ liệu. Khi các khối dữ liệu không được sao chép đủ, thì có nguy cơ mất dữ liệu, do đó, sức khỏe của hệ thống là kém. Tốt hơn là bạn đừng cố gắng chạy các tác vụ Hadoop chỉ trên một nút đơn.
Bạn không bị hạn chế phải dùng Java cho các công việc MapReduce của mình. Ví dụ cuối cùng này của MapReduce sử dụng Hadoop Streaming để hỗ trợ một trình mapper được viết bằng Python và một trình reducer có sử dụng AWK. Bạn không cần phải là một chuyên gia Java thì mới làm việc được với Map-Reduce!
Mark Twain không phải là một fan hâm mộ Cooper. Trong trường hợp này, Hadoop sẽ cung cấp một phê bình văn học đơn giản để so sánh giữa Twain và Cooper. Phép thử Flesch-Kincaid tính toán mức độ dễ đọc của một văn bản cụ thể. Một trong những yếu tố trong phân tích này là độ dài trung bình của câu. Việc phân tích cú pháp các câu hóa ra phức tạp hơn so với việc chỉ tìm kiếm dấu chấm câu. Gói phần mềm openNLP và gói phần mềm Python NLTK có các trình phân tích cú pháp câu rất tốt. Để đơn giản, ví dụ được hiển thị trong Liệt kê 8 sẽ sử dụng độ dài từ như là một sự thay thế cho số lượng các âm tiết trong một từ. Nếu bạn muốn dùng độ dài từ này cho mức tiếp theo, hãy thực hiện phép thử Flesch-Kincaid trong MapReduce, duyệt trang web và tính toán các mức dễ đọc cho các trang tin ưa thích của mình.

Liệt kê 8. Một phê bình văn học của trình mapper dựa trên Python
                
# here is the mapper we'll connect to the streaming hadoop interface
                
# the mapper is reading the text in the file - not really appreciating Twain's humor
# 
                
# modified from 
# http://www.michael-noll.com/tutorials/writing-an-hadoop-mapreduce-program-in-python/
$ cat mapper.py 
#!/usr/bin/env python
import sys
                
# read stdin
for linein in sys.stdin:
# strip blanks
linein = linein.strip()
# split into words
mywords = linein.split()
# loop on mywords, output the length of each word
for word in mywords:
# the reducer just cares about the first column, 
# normally there is a key - value pair
print '%s %s' % (len(word), 0)
            

Kết quả đầu ra của trình mapper, cho từ "Twain", sẽ là: 5 0. Các độ dài từ bằng số đều được sắp xếp theo thứ tự và được đưa tới trình rút gọn theo thứ tự sắp xếp. Trong các ví dụ được hiển thị trong Liệt kê 9 và 10, không cần sắp xếp dữ liệu để nhận được kết quả đầu ra đúng, nhưng do việc sắp xếp này được xây dựng trong cơ sở hạ tầng MapReduce nên dù sao cũng sẽ xảy ra.

Liệt kê 9. Một trình rút gọn AWK dùng cho phê bình văn học
                
# the awk code is modified from http://www.commandlinefu.com
                
# awk is calculating
#  NR - the number of words in total
#  sum/NR - the average word length
# sqrt(mean2/NR) - the standard deviation 
                
$ cat statsreducer.awk 
awk '{delta = $1 - avg; avg += delta / NR; \
mean2 += delta * ($1 - avg); sum=$1+sum } \
END { print NR, sum/NR, sqrt(mean2 / NR); }'
            


Liệt kê 10. Chạy một trình mapper Python và trình reducer AWK với Hadoop Streaming
                 
# test locally
                
# because we're using Hadoop Streaming, we can test the 
# mapper and reducer with simple pipes
                
# the "sort" phase is a reminder the keys are sorted
# before presentation to the reducer
#in this example it doesn't matter what order the 
# word length values are presented for calculating the std deviation
                
$ zcat ../DS.txt.gz  | ./mapper.py | sort | ./statsreducer.awk 
215107 4.56068 2.50734
                
# now run in hadoop with streaming
                
# CDH4
hadoop jar /usr/lib/hadoop-mapreduce/hadoop-streaming.jar \
-input HF.txt -output HFstats -file ./mapper.py -file \
./statsreducer.awk -mapper ./mapper.py -reducer ./statsreducer.awk
  
# CDH3
$ hadoop jar /usr/lib/hadoop-0.20/contrib/streaming/hadoop-streaming-0.20.2-cdh3u4.jar \
-input HF.txt -output HFstats -file ./mapper.py -file ./statsreducer.awk \
-mapper ./mapper.py -reducer ./statsreducer.awk
                
$ hls HFstats
Found 3 items
-rw-r--r--   1 cloudera supergroup   0 2012-08-12 15:38 /user/cloudera/HFstats/_SUCCESS
drwxr-xr-x   - cloudera supergroup   0 2012-08-12 15:37 /user/cloudera/HFstats/_logs
-rw-r--r--   1 cloudera ...  24 2012-08-12 15:37 /user/cloudera/HFstats/part-00000
                
$ hcat /user/cloudera/HFstats/part-00000
113365 4.11227 2.17086
                
# now for cooper
                
$ hadoop jar /usr/lib/hadoop-0.20/contrib/streaming/hadoop-streaming-0.20.2-cdh3u4.jar \
-input DS.txt.gz -output DSstats -file ./mapper.py -file ./statsreducer.awk \
-mapper ./mapper.py -reducer ./statsreducer.awk
                
$ hcat /user/cloudera/DSstats/part-00000
215107 4.56068 2.50734 
            

Những người hâm mộ Mark Twain có thể vui mừng khi biết rằng Hadoop tìm ra Cooper sử dụng các từ dài hơn và với một độ lệch tiêu chuẩn gây sốc (nhằm mục đích hài hước). Tất nhiên điều đó giả định rằng các từ ngắn hơn là tốt hơn. Hãy tiếp tục, phần tiếp theo sẽ ghi dữ liệu trong HDFS vào Informix và DB2.

Không có nhận xét nào:

Đăng nhận xét