精通HADOOP(五) - 初识Hadoop - 执行和测试Hadoop样例程序

来源:互联网 发布:2017年我国旅游数据 编辑:程序博客网 时间:2024/05/17 08:05

 

1.1 执行和测试Hadoop样例程序

在Hadoop安装目录中你会找到包含Hadoop样例程序的JAR文件,你可以用它来试用Hadoop。在你执行这些样例程序以前,你应该保证你的安装是完全的和你的执行时环境的设置是正确的。我们在前面小节中提到,check_basic_env.sh脚本能够帮助你校验安装,如果安装有任何错误,它会提示你改正。

 

1.1.1 Hadoop的样例代码

hadoop-0.19.0-examples.jar文件包含着数个可以直接运行的样例程序。我们在图标1-4中列出包含在这个JAR文件的样例程序。

图表 1‑4 hadoop-0.19.0-examples.jar文件中的样例程序

程序

描述

aggregatewordcount

计算输入文件中文字个数的基于聚合的MapReduce程序。

aggregatewordhist

生成输入文件中文字个数的统计图的基于聚合的MapReduce程序。

grep

计算输入文件中匹配正则表达式的文字个数的MapReduce程序。

join

合并排序的平均分割的数据集的作业。

multifilewc

计算几个文件的文字个数的作业。

pentomino

解决五格拼版问题的分块分层的MapReduce程序。

pi

使用蒙地卡罗法计算PI的MapReduce程序。

randomtextwriter

在一个节点上写10G随机文本的MapReduce程序。

randomwriter

在每个节点上写10G随机数据的MapReduce程序。

sleep

在每个Map和Reduce作业中休憩的程序。

sort

排序随机写入器生成的数据的MapReduce程序。

sudoku

一个九宫格游戏的解决方案。

wordcount

在输入文件中统计文字个数的统计器。

 

1.1.1.1 执行PI计算器

PI计算器样例程序通过蒙地卡罗法计算PI值。网址http://www.chem.unl.edu/zeng/joy/mclab/mcintro.html提供了关于这个算法的技术讨论。抽样数量是正方形内随机集合的点数。抽样数越多,PI值的计算就越精确。为了程序的简单性,我们只用很少的操作粗略的计算出PI的值。

PI程序使用了两个整形参数。Map作业数量和每个Map作业中的抽样数量。计算中的总共的抽样数量是Map作业的数量乘以每个Map作业中的抽样数量。

Map作业在1乘1的矩形面积内产生随机的点。对于其中的每个抽样如果满足X2+Y2 <=1, 那么这个点就在圆的里面。否则,这个点就在圆的外面。Map作业输出键值为1或者0,1代表在直径为1的圆内,0代表在直径为1的圆外,映射的数据值均为1,Reduce任务计算圆内点的数量和圆外点的数量。这两个数量的比例就是极限值PI.

在这个样例程序中,为了使程序执行得更快和有更少的输出,你会选择2个Map作业,每个作业有10个抽样,一共有20个抽样。

如果你想执行这个程序,你需要改变你的工作目录去HADOOP_HOME(通过 cd ${HADOOP_HOME}),然后,键入命令如下:

jason@cloud9:~/src/hadoop-0.19.0$ hadoop jar hadoop-0.19.0-examples.jar pi 2 10

bin/hadoop jar命令提交作业到集群中。它通过三个步骤处理命令行参数,每一个步骤处理命令行参数中的一部分。我们会在第5章会看到处理参数的细节。但是现在,我们只需要知道hadoop_0.19.0-examples.jar文件包含此应用程序的主类,而且这个类接受3个参数。

 

1.1.1.2 查看输出:输入分割,混淆,溢出和排序

列表1-3就是此应用程序的输出。

列表 1-3 样例PI程序的输出

Number of Maps = 2 Samples per Map = 10

Wrote input for Map #0

Wrote input for Map #1

Starting Job

jvm.JvmMetrics: Initializing JVM Metrics with processName=JobTracker, sessionId=

mapred.FileInputFormat: Total input paths to process : 2

mapred.FileInputFormat: Total input paths to process : 2

mapred.JobClient: Running job: job_local_0001

mapred.FileInputFormat: Total input paths to process : 2

mapred.FileInputFormat: Total input paths to process : 2

mapred.MapTask: numReduceTasks: 1

mapred.MapTask: io.sort.mb = 100

mapred.MapTask: data buffer = 79691776/99614720

mapred.MapTask: record buffer = 262144/327680

mapred.JobClient: map 0% reduce 0%

mapred.MapTask: Starting flush of map output

mapred.MapTask: bufstart = 0; bufend = 32; bufvoid = 99614720

mapred.MapTask: kvstart = 0; kvend = 2; length = 327680

mapred.LocalJobRunner: Generated 1 samples

mapred.MapTask: Index: (0, 38, 38)

mapred.MapTask: Finished spill 0

mapred.LocalJobRunner: Generated 1 samples.

mapred.TaskRunner: Task 'attempt_local_0001_m_000000_0' done.

mapred.TaskRunner: Saved output of task 'attempt_local_0001_m_000000_0' ➥

to file:/home/jason/src/hadoop-0.19.0/test-mini-mr/outmapred.

MapTask: numReduceTasks: 1

mapred.MapTask: io.sort.mb = 100

mapred.JobClient: map 0% reduce 0%

mapred.LocalJobRunner: Generated 1 samples

mapred.MapTask: data buffer = 79691776/99614720

mapred.MapTask: record buffer = 262144/327680

mapred.MapTask: Starting flush of map output

mapred.MapTask: bufstart = 0; bufend = 32; bufvoid = 99614720

mapred.MapTask: kvstart = 0; kvend = 2; length = 327680

mapred.JobClient: map 100% reduce 0%

mapred.MapTask: Index: (0, 38, 38)

mapred.MapTask: Finished spill 0

mapred.LocalJobRunner: Generated 1 samples.

mapred.TaskRunner: Task 'attempt_local_0001_m_000001_0' done.

mapred.TaskRunner: Saved output of task 'attempt_local_0001_m_000001_0' ➥

to file:/home/jason/src/hadoop-0.19.0/test-mini-mr/out

mapred.ReduceTask: Initiating final on-disk merge with 2 files

mapred.Merger: Merging 2 sorted segments

mapred.Merger: Down to the last merge-pass, with 2 segments left of ➥

total size: 76 bytes

mapred.LocalJobRunner: reduce > reduce

mapred.TaskRunner: Task 'attempt_local_0001_r_000000_0' done.

mapred.TaskRunner: Saved output of task 'attempt_local_0001_r_000000_0' ➥

to file:/home/jason/src/hadoop-0.19.0/test-mini-mr/out

mapred.JobClient: Job complete: job_local_0001

mapred.JobClient: Counters: 11

mapred.JobClient: File Systems

mapred.JobClient: Local bytes read=314895

mapred.JobClient: Local bytes written=359635

mapred.JobClient: Map-Reduce Framework

mapred.JobClient: Reduce input groups=2

mapred.JobClient: Combine output records=0

mapred.JobClient: Map input records=2

mapred.JobClient: Reduce output records=0

mapred.JobClient: Map output bytes=64

mapred.JobClient: Map input bytes=48

mapred.JobClient: Combine input records=0

mapred.JobClient: Map output records=4

mapred.JobClient: Reduce input records=4

Job Finished in 2.322 seconds

Estimated value of PI is 3.8

请注意Hadoop项目使用阿帕奇基金的log4j包来处理日志。缺省情况下,框架的输出日志是以时间戳开始的,后面跟着日志级别和产生消息的类名。除此之外,缺省情况下只有INFO和更高级别日志消息才会被打印出来。为了简介,我已经从输出中移除了时间戳和日志级别。

在日志中,你最感兴趣的就是日志输出的最后一行,它说” 计算的PI值是…”。这意味着你的Hadoop安装是成功的,它能够正确的执行你的应用程序。

下面我们将一步一步的详细查看列表2-3的输出,这能帮助你理解这个样例程序是怎么工作的,甚至可以找到程序是否出现错误。

第一段日志是在Hadoop初始化PI计算器程序时输出的,我们可以看到,你的输入是2个Map作业和每个Map作业有10个抽样。

Number of Maps = 2 Samples per Map = 10

Wrote input for Map #0

Wrote input for Map #1

然后,框架程序启动并且接管控制流,它进行输入分割(把输入分成不相干的部分称为输入分割)。

你可以从下面一行中获得作业ID,你能使用作业ID在作业控制工具中找到此作业。

Running job: job_local_0001

通过下面一行我们可以得知,一共有两个输入文件和两个输入分割。

jvm.JvmMetrics: Initializing JVM Metrics with processName=JobTracker, sessionId=

mapred.FileInputFormat: Total input paths to process : 2

mapred.FileInputFormat: Total input paths to process : 2

mapred.JobClient: Running job: job_local_0001

mapred.FileInputFormat: Total input paths to process : 2

mapred.FileInputFormat: Total input paths to process : 2

映射作业的输出会被划分为不同的输出块,每一个输出块都是排序的,这个过程被称为混淆过程。包含每一个排序的输出块的文件成为输出块。对于每一个Reduce作业,框架会从Map作业的输出中得到输出块,然后合并并且排序这些输出块得到排序块,这个过程成为排序过程。

在列表2-3的下一部分,我们可以看到Map作业的混淆过程执行的详细信息。框架获得所有Map作业的输出记录,然后把这些输出输入给唯一的一个Reduce作业(numReduceTasks:1)。如果你指定了多个Reduce作业,对于每一个Reduce作业你就会看到一个类似Finished spill N的日志。剩下的日志是用来记录输出缓冲,我们并不关注这些。

下面,你会看到:

mapred.MapTask: numReduceTasks: 1

...

mapred.MapTask: Finished spill 0

mapred.LocalJobRunner: Generated 1 samples.

mapred.TaskRunner: Task 'attempt_local_0001_m_000000_0'

done.mapred.TaskRunner: Saved output of task

'attempt_local_0001_m_000000_0'

to file:/home/jason/src/hadoop-0.19.0/test-mini-mr/out

Generated 1 samples是Map作业的最终状态的输出。Hadoop框架告诉你,第一个Map作业通过作业’attempt_local_0001_m_000000_0”完成的,而且输出已经保存到缺省的文件系统file:/home/Jason/src/hadoop-0.19.0/test-mini-mr/out。

下面一部分是排序过程的输出:

mapred.ReduceTask: Initiating final on-disk merge with 2 files

mapred.Merger: Merging 2 sorted segments

mapred.Merger: Down to the last merge-pass, with 2 segments left of

total size: 76 bytes

根据命令行参数,列表2-3运行的程序中有2个Map作业和一个Reduce作业。因为仅仅存在一个Reduce作业,所有的Map作业的输出会被组织成为一个排序的排序块。但是,两个Map作业会产生两个输出块进入排序阶段。每一个Reduce作业会在输出目录下产生一个名字为part-ON的输出文件,N是Reduce作业以0开始的递增的序数。通常来说,名字的数字部分是5位数字构成的,如果不够5位数以0补齐。

日志输出的下一部分说明了唯一的Reduce任务的执行情况:

mapred.LocalJobRunner: reduce > reduce

mapred.TaskRunner: Task 'attempt_local_0001_r_000000_0' done.

mapred.TaskRunner: Saved output of task 'attempt_local_0001_r_000000_0' to

file:/home/jason/src/hadoop-0.19.0/test-mini-mr/out

我们可以看出,样例程序把Reduce作业的输出写入文件attempt_local_0001_4_000000_0,然后,把它重命名为part-00000,保存在作业的输出目录中。

下面的日志的输出提供了详细的作业完成信息。

mapred.JobClient: Job complete: job_local_0001

mapred.JobClient: Counters: 11

mapred.JobClient: File Systems

mapred.JobClient: Local bytes read=314895

mapred.JobClient: Local bytes written=359635

mapred.JobClient: Map-Reduce Framework

mapred.JobClient: Reduce input groups=2

mapred.JobClient: Combine output records=0

mapred.JobClient: Map input records=2

mapred.JobClient: Reduce output records=0

mapred.JobClient: Map output bytes=64

mapred.JobClient: Map input bytes=48

mapred.JobClient: Combine input records=0

mapred.JobClient: Map output records=4

mapred.JobClient: Reduce input records=4

最后的两行日志并不是框架打印的,而是由PiEstimator程序代码打印的。

Job Finished in 2.322 seconds

Estimated value of PI is 3.8

 

1.1.2 测试Hadoop

Hadoop框架提供了用来测试分布式文件系统和运行在分布式文件系统的MapReduce作业的样例程序,这些测试程序被包含在hadoop-0.19.0-test.jar文件中。图标1-5是这些测试程序的列表和他们提供的功能:

图表 1‑5 hadoop-0.19.0-tests.jar文件中的测试程序

测试

描述

DFSCIOTest

测试libhdfs中的分布式I/O的基准。Libhdfs是一个为C/C++应用程序提供HDFS文件服务的共享库。

DistributedFSCheck

文件系统一致性的分布式检查。

TestDFSIO

分布式的I/O基准。

clustertestdfs

对分布式文件系统的伪分布式测试。

dfsthroughput

测量HDFS的吞吐量。

filebench

SequenceFileInputFormat和SequenceFileOutputFormat的基准,这包含BLOCK压缩,RECORD压缩和非压缩的情况。TextInputFormat和TextOutputFormat的基准,包括压缩和非压缩的情况。

loadgen

通用的MapReduce加载产生器。

mapredtest

MapReduce作业的测试和检测。

mrbench

创建大量小作业的MapReduce基准。

nnbench

NameNode的性能基准。

testarrayfile

对有键值对的文本文件的测试。

testbigmapoutput

这是一个MapReduce作业,它用来处理不可分割的大文件来产生一个标志MapReduce作业。

testfilesystem

文件系统读写测试。

testipc

Hadoop核心的进程间交互测试。

testmapredsort

用于校验MapReduce框架的排序的程序。

testrpc

对远程过程调用的测试。

testsequencefile

对包含二进制键值对的文本文件的测试。

testsequencefileinputformat

对序列文件输入格式的测试。

testsetfile

对包含二进制键值对文本文件的测试。

testtextinputformat

对文本输入格式的测试。

threadedmapbench

对比输出一个排序块的Map作业和输出多个排序块的Map作业的性能。

原创粉丝点击