MR案例(2):学生排序(单字段排序、多字段排序)

news/2024/11/17 10:49:50/

文章目录

  • 一、任务目标
    • 1. 准备数据
  • 二、实行任务
    • 1. 创建Maven项目
    • 2. 添加相关依赖
    • 3. 创建日志属性文件
    • 4. 创建学生实体类
    • 5. 创建学生映射器类
    • 6. 创建学生归并器类
    • 7. 创建学生驱动类
    • 8. 启动学生驱动器类,查看结果


一、任务目标

  • MR案例:学生排序(单字段排序、多字段排序)

1. 准备数据

  • 创建sortstudent目录,在里面创建student.txt文件
    在这里插入图片描述
  • 创建/sortstudent/input目录,执行命令:hdfs dfs -mkdir -p /sortstudent/input
    在这里插入图片描述
  • 将文本文件student.txt,上传到HDFS的/sortstudent/input目录
    在这里插入图片描述

二、实行任务

1. 创建Maven项目

  • Maven项目 - SortStudent
    在这里插入图片描述

2. 添加相关依赖

  • 在pom.xml文件里添加hadoop和junit依赖
<dependencies>                                      <!--hadoop客户端-->                                <dependency>                                    <groupId>org.apache.hadoop</groupId>        <artifactId>hadoop-client</artifactId>      <version>3.3.4</version>                    </dependency>                                   <!--单元测试框架-->                                   <dependency>                                    <groupId>junit</groupId>                    <artifactId>junit</artifactId>              <version>4.13.2</version>                   </dependency>                                   
</dependencies>                                     

3. 创建日志属性文件

  • 在resources目录里创建log4j.properties文件
log4j.rootLogger=ERROR, stdout, logfile
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - %m%n
log4j.appender.logfile=org.apache.log4j.FileAppender
log4j.appender.logfile.File=target/sortstudent.log
log4j.appender.logfile.layout=org.apache.log4j.PatternLayout
log4j.appender.logfile.layout.ConversionPattern=%d %p [%c] - %m%n

4. 创建学生实体类

  • 在net.kox.mr包里创建Student类
package net.kox.mr;import org.apache.hadoop.io.WritableComparable;import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;public class Student implements WritableComparable<Student> {private String name;private String gender;private int age;private String phone;private String major;public String getName() {return name;}public void setName(String name) {this.name = name;}public String getGender() {return gender;}public void setGender(String gender) {this.gender = gender;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public String getPhone() {return phone;}public void setPhone(String phone) {this.phone = phone;}public String getMajor() {return major;}public void setMajor(String major) {this.major = major;}@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", gender='" + gender + '\'' +", age=" + age +", phone='" + phone + '\'' +", major='" + major + '\'' +'}';}public int compareTo(Student o) {return o.getAge() - this.getAge(); // 降序}public void write(DataOutput out) throws IOException {out.writeUTF(name);out.writeUTF(gender);out.writeInt(age);out.writeUTF(phone);out.writeUTF(major);}public void readFields(DataInput in) throws IOException {name = in.readUTF();gender = in.readUTF();age = in.readInt();phone = in.readUTF();major = in.readUTF();}
}

5. 创建学生映射器类

  • 在net.kox.mr里创建StudentMapper类
package net.kox.mr;import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.NullWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper;import java.io.IOException;public class StudentMapper extends Mapper<LongWritable, Text, Student, NullWritable> {@Overrideprotected void map(LongWritable key, Text value, Context context)throws IOException, InterruptedException {// 获取行内容String line = value.toString();// 按空格拆分得到字段数组String[] fields = line.split(" ");// 获取学生信息String name = fields[0];String gender = fields[1];int age = Integer.parseInt(fields[2]);String phone = fields[3];String major = fields[4];// 创建学生对象Student student = new Student();// 设置学生对象属性student.setName(name);student.setGender(gender);student.setAge(age);student.setPhone(phone);student.setMajor(major);// 写入键值对<student,null>context.write(student, NullWritable.get());}
}

6. 创建学生归并器类

package net.kox.mr;import org.apache.hadoop.io.NullWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer;import java.io.IOException;public class StudentReducer extends Reducer<Student, NullWritable, Text, NullWritable> {@Overrideprotected void reduce(Student key, Iterable<NullWritable> values, Context context)throws IOException, InterruptedException {// 获取学生对象Student student = key;// 拼接学生信息String studentInfo = student.getName() + "\t"+ student.getGender() + "\t"+ student.getAge() + "\t"+ student.getPhone() + "\t"+ student.getMajor();// 写入键值对<studentInfo,null>context.write(new Text(studentInfo), NullWritable.get());}
}

7. 创建学生驱动类

  • 在net.kox.mr包里创建StudentDriver类
package net.kox.mr;import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FSDataInputStream;
import org.apache.hadoop.fs.FileStatus;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IOUtils;
import org.apache.hadoop.io.NullWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;import java.net.URI;public class StudentDriver {public static void main(String[] args) throws Exception {// 创建配置对象Configuration conf = new Configuration();// 设置数据节点主机名属性conf.set("dfs.client.use.datanode.hostname", "true");// 获取作业实例Job job = Job.getInstance(conf);// 设置作业启动类job.setJarByClass(StudentDriver.class);// 设置Mapper类job.setMapperClass(StudentMapper.class);// 设置map任务输出键类型job.setMapOutputKeyClass(Student.class);// 设置map任务输出值类型job.setMapOutputValueClass(NullWritable.class);// 设置Reducer类job.setReducerClass(StudentReducer.class);// 设置reduce任务输出键类型job.setOutputKeyClass(Student.class);// 设置reduce任务输出值类型job.setOutputValueClass(NullWritable.class);// 定义uri字符串String uri = "hdfs://master:9000";// 创建输入目录Path inputPath = new Path(uri + "/sortstudent/input");// 创建输出目录Path outputPath = new Path(uri + "/sortstudent/output");// 获取文件系统FileSystem fs =  FileSystem.get(new URI(uri), conf);// 删除输出目录(第二个参数设置是否递归)fs.delete(outputPath, true);// 给作业添加输入目录(允许多个)FileInputFormat.addInputPath(job, inputPath);// 给作业设置输出目录(只能一个)FileOutputFormat.setOutputPath(job, outputPath);// 等待作业完成job.waitForCompletion(true);// 输出统计结果System.out.println("======统计结果======");FileStatus[] fileStatuses = fs.listStatus(outputPath);for (int i = 1; i < fileStatuses.length; i++) {// 输出结果文件路径System.out.println(fileStatuses[i].getPath());// 获取文件系统数据字节输入流FSDataInputStream in = fs.open(fileStatuses[i].getPath());// 将结果文件显示在控制台IOUtils.copyBytes(in, System.out, 4096, false);}}
}

8. 启动学生驱动器类,查看结果

  • 运行StudentDriver 类
    在这里插入图片描述
  • 确实学生信息按照年龄降序排列了,但是做了一件我们不需要的去重,少了3条记录
  • 需要修改学生归并器类,遍历值迭代器,这样就不会去重了
    在这里插入图片描述
  • 再次运行StudentDriver 类
    在这里插入图片描述

http://www.ppmy.cn/news/4965.html

相关文章

物联网开发笔记(64)- 使用Micropython开发ESP32开发板之控制ILI9341 3.2寸TFT-LCD触摸屏进行LVGL图形化编程:控件显示

一、目的 这一节我们学习如何使用我们的ESP32开发板来控制ILI9341 3.2寸TFT-LCD触摸屏进行LVGL图形化编程&#xff1a;控件显示。 二、环境 ESP32 ILI9341 3.2寸TFT-LCD触摸屏 Thonny IDE 几根杜邦线 接线方法&#xff1a;见前面文章。 三、滑杆代码 import lvgl as lv i…

【Mitigating Voltage Attacks in Multi-Tenant FPGAs 论文笔记】

减轻多租户FPGA中的电压攻击摘要引言内容背景和相关工作INTEL STRATIX 10 FPGA上的PDN攻击Stratix 10 PDN特性定位电压下降片上监控和攻击抑制结论和未来工作结论&#xff1a;未来工作作者&#xff1a;GEORGE PROVELENGIOS, University of Massachusetts Amherst, MA, USADANIE…

华为OD机试真题 Python 实现【预订酒店】【2022.11 Q4 新题】

目录 题目 思路 考点 Code 题目 放暑假了,小明决定到某旅游景点游玩,他在网上搜索到了各种价位的酒店(长度为n的 数组A),他的心理价位是x元,请帮他筛选出k个最接近x元的酒店 (n>=k>0) ,并由低到高打印酒店的价格输入描述 第一行: n,k,x 第二行: A[o] A[1] A[2].…

Java项目:基于jsp+mysql+Spring+mybatis的SSM在线网络图书商城

作者主页&#xff1a;源码空间站2022 简介&#xff1a;Java领域优质创作者、Java项目、学习资料、技术互助 文末获取源码 项目介绍 本项目分为前后台&#xff0c;有管理员与用户两种角色&#xff1b; 管理员角色包含以下功能&#xff1a; 管理员登录,商品分类管理,商品管理,商…

Linux c编程之IO复用机制

一、说明 在实际网络程序中,比如服务器程序,需要使用IO复用机制来处理多个客户端的连接和数据收发。Linux系统下常用的IO复用机制有三种:select、poll、epoll。   poll是Linux中的字符设备驱动中的一个函数。Linux 2.5.44版本后,poll被epoll取代。   select用于监视文件…

海量数据小内存!从未出现过的数在哪里

文章目录题目要求1&#xff09;内存 1G2&#xff09;内存 3 KB3&#xff09;内存 有限变量举例题目 现在有 40 亿个无符号整数&#xff0c;无符号整数的范围是 0 ~ 232-1&#xff08;42亿&#xff09;&#xff0c;哪怕 40 亿个数完全不同&#xff0c;在该范围中也总有没有出现…

29.图像卷积代码实现

1. 互相关运算 接下来&#xff0c;我们在corr2d函数中实现如上过程&#xff0c;该函数接受输入张量X和卷积核张量K&#xff0c;并返回输出张量Y。 import torch from torch import nn from d2l import torch as d2ldef corr2d(X,K): # X是输入&#xff0c;K是核矩阵计算二维互…

随着企业信息化发展之源代码防泄密需求分析

源代码防泄密需求&#xff1a; 随着企业信息化发展的日益增长&#xff0c;软件行业厂商之间的竞争也愈加白热化&#xff0c;加上国内对知识产权的不够重视、山寨模仿产品的横行。保护源代码、保证企业的核心竞争力&#xff0c;成为众多软件研发企业的第一要务。那么企业应该如…