hadoop计算pi的源码及注释
时间: 2024-03-26 19:34:26 浏览: 170
以下是Hadoop计算Pi的源代码及注释:
```java
// PiMapper.java
import java.io.IOException;
import java.util.Random;
import org.apache.hadoop.io.*;
import org.apache.hadoop.mapreduce.*;
public class PiMapper extends Mapper<Object, Text, IntWritable, IntWritable> {
private final static IntWritable one = new IntWritable(1);
private static Random rndm = new Random();
public void map(Object key, Text value, Context context) throws IOException, InterruptedException {
int numThrows = 10000; // 每个Mapper的投掷次数
int inCircle = 0; // 落在圆内的次数
for (int i = 0; i < numThrows; i++) {
// 在 [-1, 1] 的范围内随机生成一个点
double x = 2 * rndm.nextDouble() - 1.0;
double y = 2 * rndm.nextDouble() - 1.0;
// 判断该点是否落在圆内
if (x * x + y * y <= 1.0) {
inCircle++;
}
}
// 将落在圆内的次数作为Key,1作为Value写入Context
context.write(new IntWritable(inCircle), one);
}
}
```
```java
// PiReducer.java
import java.io.IOException;
import org.apache.hadoop.io.*;
import org.apache.hadoop.mapreduce.*;
public class PiReducer extends Reducer<IntWritable, IntWritable, IntWritable, DoubleWritable> {
private DoubleWritable result = new DoubleWritable();
public void reduce(IntWritable key, Iterable<IntWritable> values, Context context)
throws IOException, InterruptedException {
int sum = 0;
int count = 0;
// 统计Key对应的Value的总和
for (IntWritable val : values) {
sum += val.get();
count++;
}
// 计算Pi的近似值
double pi = ((double) sum / (double) count) * 4.0;
// 将近似值作为Value写入Context
result.set(pi);
context.write(key, result);
}
}
```
```java
// PiDriver.java
import java.io.IOException;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.*;
import org.apache.hadoop.mapreduce.*;
public class PiDriver {
public static void main(String[] args) throws Exception {
Configuration conf = new Configuration();
Job job = Job.getInstance(conf, "Pi Estimation");
// 设置Mapper
job.setMapperClass(PiMapper.class);
job.setMapOutputKeyClass(IntWritable.class);
job.setMapOutputValueClass(IntWritable.class);
// 设置Reducer
job.setReducerClass(PiReducer.class);
job.setOutputKeyClass(IntWritable.class);
job.setOutputValueClass(DoubleWritable.class);
// 设置InputFormat
job.setInputFormatClass(TextInputFormat.class);
// 设置OutputFormat
job.setOutputFormatClass(TextOutputFormat.class);
// 设置输入路径和输出路径
FileInputFormat.addInputPath(job, new Path(args[0]));
FileOutputFormat.setOutputPath(job, new Path(args[1]));
// 提交作业并等待完成
System.exit(job.waitForCompletion(true) ? 0 : 1);
}
}
```
注释:
1. `PiMapper`类是一个Mapper类,它继承自`Mapper<Object, Text, IntWritable, IntWritable>`。它的输入键是`Object`,输入值是`Text`,输出键是`IntWritable`,输出值是`IntWritable`。
2. 在`PiMapper`类中,我们首先定义了一个`IntWritable`类型的常量`one`,它的值为1。接着,我们使用`java.util.Random`类创建了一个随机数生成器`rndm`。
3. `map`方法是`Mapper`类中的一个重要方法,它的作用是将输入键值对转换为输出键值对。在`PiMapper`类中,我们将每个Mapper的投掷次数设置为10000,然后在这个范围内随机生成一个点,判断该点是否落在圆内。如果是,我们将`inCircle`变量加1。最后,将落在圆内的次数作为Key,1作为Value写入Context。
4. `PiReducer`类是一个Reducer类,它继承自`Reducer<IntWritable, IntWritable, IntWritable, DoubleWritable>`。它的输入键是`IntWritable`,输入值是`IntWritable`,输出键是`IntWritable`,输出值是`DoubleWritable`。
5. 在`PiReducer`类中,我们首先定义了一个`DoubleWritable`类型的变量`result`。在`reduce`方法中,我们统计了Key对应的Value的总和和Value的数量。然后,根据公式计算Pi的近似值,将近似值作为Value写入Context。
6. `PiDriver`类是一个驱动程序。在`main`方法中,我们首先创建了一个`Configuration`对象和一个`Job`对象。然后,我们设置了Mapper、Reducer、InputFormat和OutputFormat。接着,我们设置了输入路径和输出路径。最后,我们提交作业并等待完成。
阅读全文