圆周率π的近似计算(三)-MapReduce分布式计算入门_mapreduce计算圆周率(1)

img
img

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

* 第二阶段 是对切片中的数据按照一定的规则解析成 key,value 元组.默认规则是把每一行文本内容解析成键值对. key 是每一行的起始位置,value 是本行的文本内容.(TextInputFormat)
* 第三阶段 是调用Mapper 类中的Map 方法. 上阶段每解析出来一个 k,v 调用一次 map 方法.输出同样是键值对,但是可以有多个输出.
* 第四阶段 是按照一定的规则对第三阶段输出的键值对进行分区。 默认是只有一个区。 分区的数量就是 Reducer 任务运行的数量。默认只有一个Reducer 任务。
* 第五阶段是对每个分区中的键值对进行排序。如果有第六阶段,那么进入第六阶段;如果没有,直接输出到文件中。
* 第六阶段是对数据进行局部聚合处理,也就是 combiner 处理。 键相等的键值对会调用一次 reduce 方法。经过这一阶段,数据量会减少。 本阶段默认是没有的。
  1. Reduce 阶段执行流程

    • 第一阶段是 Reducer 任务会主动从 Mapper 任务复制其输出的键值对。Mapper 任务可能会有很多,因此 Reducer 会复制多个 Mapper 的输出。
    • 第二阶段是把复制到 Reducer 本地数据,全部进行合并,即把分散的数据合并成一个大的数据。再对合并后的数据排序。
    • 第三阶段是对排序后的键值对调用 reduce 方法。 键相等的键值对调用一次reduce 方法,每次调用会产生零个或者多个键值对。最后把这些输出的键值对写入到 HDFS 文件中。

进行圆周率 π 的分布式计算

从分 MapReduce 的执行流程看出,分布式框架已经帮我们实现了任务的分发,因此我们的关注点就基本可以不用考虑关于分布式方面的任务,我们主要需要关注的就是 map 方法的构建
,和 reduce 方法的构建.

数学模型

进行分布式计算的任务有个先决条件,那就是可以进行并行计算,就是各 map 之间相互独立,无依赖关系.

因此,我们在建立数学模型时最好是一个重复计算无相互关联的模型,而 蒙特卡洛 的模型恰好符合这种特点,因此我们依次构建模型.

在上篇**文章**中,我们采用的通过面积比的方式来近似求解 圆周率 π ,即正方形面积为 1 ,扇形面积为 π/4,则正方形和扇形的面积比为 π/4,求得这个面积比,我们就能得到最后的 π;

蒙特卡罗方法,就是将面积比转化为概率问题求解,就是在正方形中取一随机点进行重复试验,统计出这个点落在扇形中的概率.用这个概率去描述扇形和正方形的面积比,求得概率即可近似求出圆周率 π 的大小;

随机试验的优点是,每次试验相互独立互不影响,缺点随机性大,数据不稳定,一般只用做近似求解.

综上,我们可以将 求解圆周率的任务 转化为随机试验的统计工作.

实现方法
  1. 首先我们给出Mapper阶段方法
public class SolvingPiMapper extends Mapper<LongWritable, Text, Text, Text> {       
    /**
     * key 输入 读取文件的起始位置
     * value 输入 文件中一行的内容
     * context 输出 <k,v>形式
     */
    @Override
    protected void map(LongWritable key, Text value, Mapper<LongWritable, Text, Text, Text>.Context context)
            throws IOException, InterruptedException {
        //将从文件中读取的随机试验次数解析出来
        String num = value.toString();
        Integer totle = new Integer(num);
        //声明随机试验中落点在扇形中数量
        int sum = 0;
        //进行随机试验并统计
        for(int i=0;i<totle;i++){
            double x = Math.random();
            double y = Math.random();
            if((x*x+y*y)<1){
                sum++;
            }
        }
        //将最后结果输出
        context.write(new Text("PI"), new Text(totle+"--"+sum));
    }
}

  1. 给出 reduce 方法
public class SolvingPiReducer extends Reducer<Text, Text, Text, DoubleWritable> {
    /**
     * name 输入的 "PI"
     * message 输入的"totle--num"
     * context 输出的<k,v>
     * 所有键位"PI"的输入都用这个方法进行处理
     */
    @Override
    protected void reduce(Text name, Iterable<Text> message, Reducer<Text, Text, Text, DoubleWritable>.Context context)
            throws IOException, InterruptedException {
        //声明试验进行的总数
        long sumTotle =0;
        //声明落点在扇形区域中的总数
        long sumOrder =0;
        //解析输入的message信息,从这提取上述两个值
        for (Text text : message) {
            String[] nums = text.toString().split("--");
            sumTotle+= new Integer(nums[0]);
            sumOrder+= new Integer(nums[1]);
        }
        //System.out.println("π的近似值为"+sumOrder*4.0/sumTotle);
        //输出最后结果
        context.write(name,new DoubleWritable(sumOrder*4.0/sumTotle));
    }
}

解析 map 方法返回的信息,进行汇总并输出最后结果.
3. 定义一个主类,用来描述job并提交job

public class SolvingPiRunner {
    //把业务逻辑相关的信息(哪个是 mapper,哪个是 reducer,要处理的数据在哪里,输出的结果放在哪里……)描述成一个 job 对象
    //把这个描述好的 job 提交给集群去运行
    public static void main(String[] args) throws Exception {
        //用户自定义输入
        System.out.println("请输入你想分的片数:");
        Scanner sc = new Scanner(System.in);
        int pice=new Integer(sc.nextLine());
        System.out.println("请输入你每片执行多少次:");
        String line=sc.nextLine();
        //按照分片生成文件(在实际环境中需要在hdfc中创建文件)
        for(int i=0;i<pice;i++){
            BufferedWriter bw = new BufferedWriter(new FileWriter(new File("D:\\hadoop\\input\\"+(i+1)+".txt")));
            bw.write(line);
            bw.close();
        }

        //把业务逻辑相关的信息(哪个是 mapper,哪个是 reducer,要处理的数据在哪里,输出的结果放在哪里……)描述成一个 job 对象
        //把这个描述好的 job 提交给集群去运行
        Configuration conf = new Configuration();
        Job job = Job.getInstance(conf);
        //知道这个job所在jar包
        job.setJarByClass(SolvingPiRunner.class);

        job.setMapperClass(SolvingPiMapper.class);
        job.setReducerClass(SolvingPiReducer.class);
        //设置我们的业务逻辑Mapper类的输出key 和  value 的数据
        job.setMapOutputKeyClass(Text.class);
        job.setMapOutputValueClass(Text.class);
        //设置我们的业务逻辑Reducer 类的输出Key和value 的数据类型
        job.setOutputKeyClass(Text.class);
        job.setOutputValueClass(DoubleWritable.class);
        //指定要处理的数据所在的位置
        FileInputFormat.setInputPaths(job, "D:\\hadoop\\input\\*.txt");
        //指定处理完成后,结果所保存的位置
        FileOutputFormat.setOutputPath(job, new Path("D:\\hadoop\\output\\result"));
        //向yarn集群提交这个job

        boolean res = job.waitForCompletion(true);
        System.exit(res?0:1);
    }
}

在windows环境下模拟集群环境执行测试;

遇到的问题
  • 启动问题报错

img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上大数据知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

需要这份系统化资料的朋友,可以戳这里获取

,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上大数据知识点,真正体系化!**

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

需要这份系统化资料的朋友,可以戳这里获取

  • 9
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值