Hadoop Partition函数应用(归档)

news2024/11/28 14:38:12

一、实例描述

  在这个实例里我们使用简单的数据集,里面包含多条数据,每条数据由姓名、年龄、性别和成绩组成。实例要求是按照如下规则归档用户。

  1.找出年龄小于20岁中男生和女生的最大分数
  2.找出20岁到50岁男生和女生的最大分数
  3.找出50岁以上的男生和女生的最大分数

  样例输入: 

  样例输出:

  1.年龄小于20岁中男生和女生的最大分数 

  2.20岁到50岁男生和女生的最大分数

  3.50岁以上的男生和女生的最大分数

二、设计思路

  基于实例需求,我们通过以下几步完成:第一步,编写Mapper类,按需求将数据集解析为key=gender,value=name+age+score,然后输出。第二步,编写Partitioner类,按年龄段,将结果指定给不同的Reduce执行。第三步,编写Reduce类,分别统计出男女学生的最高分。

      这里简单介绍一下Partition的概念和使用:

  得到map产生的记录后,他们该分配给哪些reducer来处理呢?hadoop默认是根据散列值来派发,但是实际中,这并不能很高效或者按照我们要求的去执行任务。例如,经过partition处理后,一个节点的reducer分配到了20条记录,另一个却分配到了10W万条,试想,这种情况效率如何。又或者,我们想要处理后得到的文件按照一定的规律进行输出,假设有两个reducer,我们想要最终结果中part-00000中存储的是”h”开头的记录的结果,part-00001中存储其他开头的结果,这些默认的partitioner是做不到的。所以需要我们自己定制partition来选择reducer。自定义partitioner很简单,只要自定义一个类,并且继承Partitioner类,重写其getPartition方法就好了,在使用的时候通过调用Job的setPartitionerClass指定一下即可。

    MapReduce基于key的全排序的原理:

  如何使用mapreduce来做全排序?最简单的方法就是使用一个partition,因为一个partition对应一个reduce的task,然而reduce的输入本来就是对key有序的,所以很自然地就产生了一个全排序文件。但是这种方法在处理大型文件时效率极低,因为一台机器必须处理所有输出文件,从而完全丧失了mapreduce所提供的并行架构的优势。

  如果是分多个partition呢,则只要确保partition是有序的就行了。首先创建一系列排好序的文件;其次,串联这些文件(类似于归并排序);最后得到一个全局有序的文件。比如有1000个1-10000的数据,跑10个ruduce任务,如果进行partition的时候,能够将在1-1000中数据的分配到第一个reduce中,1001-2000的数据分配到第二个reduce中,以此类推。即第n个reduce所分配到的数据全部大于第n-1个reduce中的数据。这样,每个reduce出来之后都是有序的了,我们只要concat所有的输出文件,变成一个大的文件,就都是有序的了。

  这时候可能会有一个疑问,虽然各个reduce的数据是按照区间排列好的,但是每个reduce里面的数据是乱序的啊?当然不会,不要忘了排序是MapReduce的天然特性 — 在数据达到reducer之前,mapreduce框架已经对这些数据按key排序了。

  但是这里又有另外一个问题,就是在定义每个partition的边界的时候,可能会导致每个partition上分配到的记录数相差很大,这样数据最多的partition就会拖慢整个系统。我们期望的是每个partition上分配的数据量基本相同,hadoop提供了采样器帮我们预估整个边界,以使数据的分配尽量平均。

  在Hadoop中,patition我们可以用TotalOrderPartitioner替换默认的分区,然后将采样的结果传给他,就可以实现我们想要的分区。在采样时,可以使用hadoop的几种采样工具,如RandomSampler,InputSampler,IntervalSampler。

 三、程序代码

  程序代码如下:

import java.io.IOException;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.Partitioner;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import org.apache.hadoop.util.GenericOptionsParser;


public class Gender {

    private static String spiltChar = "\t";    //  字段分隔符

    public static class GenderMapper extends Mapper<LongWritable, Text, Text, Text>{

        //  调用map解析一行数据,该行的数据存储在value参数中,然后根据\t分隔符,解析出姓名,年龄,性别和成绩
        @Override
        protected void map(LongWritable key, Text value,Mapper<LongWritable, Text, Text, Text>.Context context)
                throws IOException, InterruptedException {
            //  super.map(key, value, context);
            String [] tokens = value.toString().split(spiltChar);
            String gender = tokens[2];
            String nameAgeScore = tokens[0]+spiltChar+tokens[1]+spiltChar+tokens[3];
            //  输出 key=gender  value=name+age+score
            context.write(new Text(gender), new Text(nameAgeScore));
        }
    }

    //  合并 Mapper 输出结果
    public static class GenderCombiner extends Reducer<Text, Text, Text, Text>{
        @Override
        protected void reduce(Text key, Iterable<Text> values,Reducer<Text, Text, Text, Text>.Context context)
                throws IOException, InterruptedException {
            //  super.reduce(arg0, arg1, arg2);
            int maxScore = Integer.MIN_VALUE;
            int score = 0;
            String name = " ";
            String age = " ";
            for(Text val:values){
                String [] valTokens = val.toString().split(spiltChar);
                score = Integer.parseInt(valTokens[2]);
                if(score>maxScore){
                    name = valTokens[0];
                    age = valTokens[1];
                    maxScore = score;
                }
            }
            context.write(key, new Text(name + spiltChar + age + spiltChar + maxScore));
        }
    }

    //  根据age年龄段将map输出结果均匀分布在reduce 上
    public static class GenderPartitioner extends Partitioner<Text, Text>{
        @Override
        public int getPartition(Text key, Text value, int numReduceTasks) {
            String [] nameAgeScore = value.toString().split(spiltChar);
            int age = Integer.parseInt(nameAgeScore[1]);

            //  默认指定分区0
            if (numReduceTasks == 0) {
                return 0;
            }
            //  年龄小于等于20,指定分区0
            if (age <= 20) {
                return 0;
            }else if (age <= 50) {          //  年龄大于20,小于等于50,指定分区1
                return 1 % numReduceTasks;
            }else {                          //  剩余年龄指定分区2
                return 2 % numReduceTasks;
            }
        }
    }

    //  统计出不同性别的最高分
    public static class GenderReducer extends Reducer<Text, Text, Text, Text>{
        @Override
        protected void reduce(Text key, Iterable<Text> values,Reducer<Text, Text, Text, Text>.Context context)
                throws IOException, InterruptedException {
            //  super.reduce(arg0, arg1, arg2);
            int maxScore = Integer.MIN_VALUE;
            int score = 0;
            String name = " ";
            String age = " ";
            String gender = " ";

            //  根据key,迭代value集合,求出最高分
            for(Text val:values){
                String[] valTokens = val.toString().split(spiltChar);
                score = Integer.parseInt(valTokens[2]);
                if (score > maxScore) {
                    name = valTokens[0];
                    age = valTokens[1];
                    gender = key.toString();
                    maxScore = score;
                }
            }
            context.write(new Text(name), new Text("age:" + age + spiltChar + "gender:" + gender + spiltChar + "score:" + maxScore));
        }
    }

    public static void main(String[] args) throws IOException, ClassNotFoundException, InterruptedException {
        Configuration conf = new Configuration();
        String[] otherArgs = new GenericOptionsParser(conf,args).getRemainingArgs();
        if(otherArgs.length!=2){
            System.out.println("Usage:wordcount <in> <out>");
            System.exit(2);
        }
        Job job = new Job(conf,"Gender");
        job.setJarByClass(Gender.class);

        job.setMapperClass(GenderMapper.class);
        job.setReducerClass(GenderReducer.class);
        job.setMapOutputKeyClass(Text.class);
        job.setMapOutputValueClass(Text.class);
        job.setOutputKeyClass(Text.class);
        job.setOutputValueClass(Text.class);

        job.setCombinerClass(GenderCombiner.class);
        job.setPartitionerClass(GenderPartitioner.class);
        job.setNumReduceTasks(3);            //  reduce个数设置为3

        FileInputFormat.addInputPath(job,new Path(args[0]));
        FileOutputFormat.setOutputPath(job, new Path(args[1]));
        System.exit(job.waitForCompletion(true)?0:1);
    }

}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/423228.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

神器集合!这12个免费工具可以让您的工作更高效

好的工具&#xff0c;能够帮助我们更高效地完成工作&#xff0c;节省时间和精力; 节省出更多的摸鱼时间&#xff01; 本文将介绍 12 款绝佳的免费效率工具&#xff0c;这些工具可以让你事半功倍&#xff0c;提高工作效率。无论你是一名程序员、设计师、学生还是白领&#xff0c…

微观世界的详细地图:微生物生态位

是什么定义了微生物的栖息地 - 生态位&#xff1f;它是温度、湿度和营养成分等环境因素的组合。很难预测每一个因素的确切贡献度。Bas E. Dutilh研究组 基于生活在一起的微生物群体&#xff0c;重新定义了微生物生态位。无论是在温泉、人体肠道还是深海中&#xff0c;微生物几乎…

助力工业物联网,工业大数据之ODS层构建:需求分析【八】

文章目录01&#xff1a;ODS层构建&#xff1a;需求分析02&#xff1a;ODS层构建&#xff1a;创建项目环境03&#xff1a;ODS层构建&#xff1a;代码导入01&#xff1a;ODS层构建&#xff1a;需求分析 目标&#xff1a;掌握ODS层构建的实现需求 路径 step1&#xff1a;目标step…

二甲医院云his系统源码,已在多家医院全面实际使用,系统稳定可靠

云his系统源码&#xff0c;基于云计算技术的B/S架构的HIS系统源码 文末获取联系&#xff01; 基于云计算技术的B/S架构的HIS系统&#xff0c;为基层医疗机构提供标准化的、信息化的、可共享的医疗信息管理系统&#xff0c;实现医患事务管理和临床诊疗管理等标准医疗管理信息系统…

HTML中的图片标签,真的如你认为的那么简单吗?

今天讨论一个很有意思的话题&#xff1a; HTML 中的图片真的那么简单吗&#xff1f; HTML 中的图片 <img>&#xff1a;图像嵌入元素 MDN Web Docs 地址&#xff1a;https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/img 在一开始时&#xff0c;Web 仅有文…

摄影知识整理

目录 焦距 焦距分类 对焦 相机的MF与AF 自动对焦操作 自动对焦方式 镜头防抖 防抖模式 景深 景深的作用 影响景深的因素 景深预览 摄影三大元素 光圈 光圈的作用 光圈与景深的关系 感光度&#xff08;ISO) 注意 感光度的作用 快门 B门与T门 快门速度 闪…

软件工程环境(Maven)—javaEE

文章目录1.如何使用Maven1.1创建一个Maven项目&#xff08;项目使用Maven来进行构建&#xff09;1.2设置项目的信息1.3配置Maven项目&#xff08;在项目路径下pom.xml&#xff0c;Maven配置文件&#xff09;1.4验证配置成功2.Maven的使用2.1观察开发项目结构2.2xml文件2.3Maven…

既然Linux是基于UNIX的操作系统,那为什么UNIX收费而Linux免费?

首先说是不是?再说为什么? 一. Linux是基于UNIX吗? Linux是类UNIX系统&#xff0c;那什么是类UNIX系统呢&#xff1f; 类UNIX系统是指继承UNIX的设计风格演变出来的系统。 类UNIX系统就是长得像UNIX、但实际不是UNIX的系统&#xff1b; 其实本质上就是借鉴了UNIX系统的界…

激光和相机的标定---手动标定的方法

一、手动标定 代码工程&#xff1a;GitHub - Livox-SDK/livox_camera_lidar_calibration: Calibrate the extrinsic parameters between Livox LiDAR and camera 这是Livox提供的手动校准Livox雷达和相机之间外参的方法&#xff0c;并在Mid-40&#xff0c;Horizon和Tele-15上进…

C51 - SPI读写ADC

TSC20461> 项目概述2> 硬件设计3> TSC20463.1> TSC2046功能3.2> TSC2046控制命令3.3> 控制命令总结3.4> SPI协议3.5> 数据转换4> 软件编程4.1> 实现功能4.2> 编程思路4.3> SPI驱动4.4> TSC2046驱动5> 联调测试5.1> VBAT的1/4分压…

【论文简述】DELS-MVS: Deep Epipolar Line Search for Multi-View Stereo(WACV 2023)

一、论文简述 1. 第一作者&#xff1a;Mattia Rossi 2. 发表年份&#xff1a;2023 3. 发表期刊&#xff1a;WACV 4. 关键词&#xff1a;MVS、3D重建、极线搜素 5. 探索动机&#xff1a;目前的方法无论是深度值还是逆深度值&#xff0c;都需要提前确定深度值范围&#xff0…

java反序列化 URLDNS链分析

前言 终于可算是来到java反序列化&#xff0c;在菠萝师傅的一番提醒&#xff0c;我认识到自己不能继续在简单的游荡了&#xff0c;要来到难的地方了。 也庆祝自己终于拥有了勇气。 分析 基础 我相对喜欢先代码在讲原理&#xff0c;这里不怎么了解序列化可以去复习一下javase 可…

黑盒测试用例设计

目录 前言&#xff1a; 一、黑盒测试 二、实验目的 三、实验内容 四、实验步骤 五、实验过程 题目一 1、等价类划分表 2、设计测试用例 3、缺陷 4、代码实现 5、测试结果 题目二 设计测试用例 题目一示例代码&#xff08;java编写&#xff09; 总结 前言&#x…

苹果pencil和平替笔有哪些区别?性价比平替电容笔排行榜

而对于那些把ipad当做学习工具的学生党而言&#xff0c;电容笔就成了日常的必备品。但因为苹果Pencil的售价太贵了&#xff0c;学生们都买不起。因此&#xff0c;最好的选择还是平替电容笔。作为一个ipad的忠实用户&#xff0c;同时也是一个数码产品的热衷者&#xff0c;这两年…

1797F Li Hua and Path(Min-rt树,Max-rt树)

题目链接 题意 &#xff1a; 给你一个大小为nnn的树&#xff0c;我们想求解一个问题&#xff0c;问题的定义是找有多少条路径满足恰好满足路径的端点是路径的最小值ororor最大值条件之一&#xff0c;【注】不能同时满足路径的两个端点是最小值又是最大值 现在增加mmm个操作&am…

【Unity】基于AVFoundation开发MacOS摄像头(二)

【Unity】基于AVFoundation开发MacOS摄像头&#xff08;一&#xff09;_GrimRaider的博客-CSDN博客实现一个Camera设备驱动&#xff0c;代替unity自带WebCamTexturehttps://blog.csdn.net/GrimRaider/article/details/130127229 目标1&#xff1a;实现bridge&#xff0c;创建一…

【Java数据结构——环形链表】判断链表成环与寻找链表成环的入口节点(经典)

判断链表是否成环https://leetcode.cn/problems/linked-list-cycle/description/ 解题核心思路&#xff1a; 定义快慢指针初始引用指向链表的头节点&#xff0c;快指针每向后走两步&#xff0c;慢指针走一步。如果链表中存在环&#xff0c;则快慢指针一定会在某次移动后相遇。 …

一文看懂“低代码、零代码”是什么?有什么区别?

低代码和零代码近几年热度一直居高不下&#xff0c;乍一看&#xff0c;很容易混淆低代码和零代码开发平台—— 因为它们都是传统开发的替代方案&#xff0c;旨在通过类似于可视化编程的功能加速软件开发过程。 但二者根本不是一回事。从开发人员经验 、目标角色到使用场景&…

C++ 学习4

C设计原则 高内聚低耦合 内聚就是一个模块内各个元素彼此结合的紧密程度&#xff0c;高内聚就是一个模块内各个元素彼此结合的紧密程度高。 所谓高内聚是指一个软件模块是由相关性很强的代码组成&#xff0c;只负责一项任务&#xff0c;也就是常说的单一责任原则。 耦合&am…

计算机网络 - TCP的效率与特性

前言 本篇是介绍部分TCP的特性&#xff0c;了解TCP提高传输速率的机制&#xff1b;如有错误&#xff0c;请在评论区指正&#xff0c;让我们一起交流&#xff0c;共同进步&#xff01; 文章目录前言1. 滑动窗口2. 流量控制3.拥塞控制4.延时应答5. 捎带应答6. 面向字节流7. 异常…