从零开始学习Hadoop--补一 一个实际的例子

本文从零开始介绍学习Hadoop,通过分析Pi值估算原理,讲解了使用Hadoop MapReduce的旧版和新版API来计算Pi值的程序。文章详细阐述了MapReduce的工作流程,包括HalthonSequence算法生成样本点,以及Map和Reduce任务的具体实现。此外,还给出了新版API的代码示例和编译运行方法。
摘要由CSDN通过智能技术生成

1.Pi值估算原理

Hadoop自带的例子中,有一个计算Pi值的例子。这例子比较全面,它用的API是旧版的。本章先分析一下这个例子,然后再用新版的API重新实现一下。


这个程序的原理是这样的。假如有一个边长为1的正方形。以正方形的一个端点为圆心,以1为半径,画一个圆弧,于是在正方形内就有了一个直角扇形。在正方形里随机生成若干的点,则有些点是在扇形内,有些点是在扇形外。正方形的面积是1,扇形的面积是0.25*Pi。设点的数量一共是n,扇形内的点数量是nc,在点足够多足够密集的情况下,会近似有nc/n的比值约等于扇形面积与正方形面积的比值,也就是nc/n= 0.25*Pi/1,即Pi = 4*nc/n


如何生成随机点?最简单的方式是在[0,1]的区间内每次生成两个随机小数作为随机点的xy坐标。可惜这种生成方式效果不够好,随机点之间有间隙过大和重叠的可能,会让计算精度不够高。Halton序列算法生成样本点的效果要好得多,更均匀,计算精度比随机生成的点更高,因此这个例子用Halton序列算法生成点集。关于Halton序列可以参考这里http://orion.math.iastate.edu/reu/2001/voronoi/halton_sequence.html和这里http://www.aae.wisc.edu/dphaneuf/AAE%20875/Halton%20sequences.pdf,在这里就不详细说了。


在正方形内生成的样本点越多,计算Pi值越精确,这样,这个问题就很适合用Hadoop来处理啦。假设要在正方形内生成1000万个点,可以设置10Map任务,每个Map任务处理100万个点,也可以设置100Map任务,每个Map任务处理10万个点。

2.旧版APIPi值估算MapReduce程序

此处带来来自Hadoop的示例程序。

为了计算,设置10Map任务,每个任务处理1000个点,具体流程是这样的:

1)运行PiEstimatorMapReduce程序,输入参数是101000,意思是设置10Map任务,每个Map任务处理1000个点。


2)PiEstimator进行初始化。初始化时,有一个步骤是在HDFS上生成一个目录,也就是输入目录。这个目录下有10个序列文件。Map任务的数量的数量决定序列文件的数量,PiEstimator就生成有10个序列文件。每个序列文件保存两个整数,分别是要处理的样本点在Halton序列的序号和生成样本点的数量。也就是说,第一个文件的内容是”0,1000”,第二个文件的内容是”1000,1000”,第三个文件的内容是“2000,1000”,第四个文件的内容是“3000,1000”,以此类推。如果用Halton序列算法生成一万个样本点,那么,第一个Map任务生成的点的序号是从0999,第二个Map任务生成的点的序号是从10001999,第三个Map任务生成的点的序号是从20002999,以此类推。Halton序列算法生成随机点的的唯一参数是序号。


3)PiEstimator运行MapReduce任务。


4)PiEstimatorMapReduce的输出目录读取两个整数,它们分别是直角扇形内的点的数量和直角扇形外的点的数量。


5)根据4)的结果数值,计算Pi值,然后返回。


PiEstimator.java文件的对应PiEstimator类。PiEstimator类有三个内部类,分别是HalthonSequence类,PiMapper类,PiReducer类。HalthonSequence类负责产生样本点,PiMapper类是Map过程,PiReducer类是Reduce过程。


PiRefuce.java的代码如下:

packageorg.apache.hadoop.examples;


importjava.io.IOException;

importjava.math.BigDecimal;

importjava.util.Iterator;


importorg.apache.hadoop.conf.Configured;

importorg.apache.hadoop.fs.FileSystem;

importorg.apache.hadoop.fs.Path;

importorg.apache.hadoop.io.BooleanWritable;

importorg.apache.hadoop.io.LongWritable;

importorg.apache.hadoop.io.SequenceFile;

importorg.apache.hadoop.io.Writable;

importorg.apache.hadoop.io.WritableComparable;

importorg.apache.hadoop.io.SequenceFile.CompressionType;

importorg.apache.hadoop.mapred.FileInputFormat;

importorg.apache.hadoop.mapred.FileOutputFormat;

importorg.apache.hadoop.mapred.JobClient;

importorg.apache.hadoop.mapred.JobConf;

importorg.apache.hadoop.mapred.MapReduceBase;

importorg.apache.hadoop.mapred.Mapper;

importorg.apache.hadoop.mapred.OutputCollector;

importorg.apache.hadoop.mapred.Reducer;

importorg.apache.hadoop.mapred.Reporter;

importorg.apache.hadoop.mapred.SequenceFileInputFormat;

importorg.apache.hadoop.mapred.SequenceFileOutputFormat;

importorg.apache.hadoop.util.Tool;

importorg.apache.hadoop.util.ToolRunner;


public classPiEstimator extends Configured implements Tool {

//临时目录的路径,保存运行中的文件数据。

static privatefinal Path TMP_DIR = new Path(

PiEstimator.class.getSimpleName()+ "_TMP_3_141592654");


//Halton序列类,产生随机点。

private staticclass HaltonSequence {

static finalint[] P = {2, 3};

static finalint[] K = {63, 40};


private longindex;

privatedouble[] x;

privatedouble[][] q;

privateint[][] d;


//构造函数

HaltonSequence(longstartindex) {

index =startindex;

x = newdouble[K.length];

q = newdouble[K.length][];

d = newint[K.length][];

for(int i= 0; i < K.length; i++) {

q[i] =new double[K[i]];

d[i] =new int[K[i]];

}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值