MR实战:学生信息排序

文章目录

  • 一、实战概述
  • 二、提出任务
  • 三、完成任务
    • (一)准备数据
      • 1、在虚拟机上创建文本文件
      • 2、上传文件到HDFS指定目录
    • (二)实现步骤
      • 1、创建Maven项目
      • 2、添加相关依赖
      • 3、创建日志属性文件
      • 4、创建学生实体类
      • 5、创建学生映射器类
      • 5、创建学生归并器类
      • 6、创建学生驱动器类
      • 7、启动学生驱动器类,查看结果
  • 四、拓展练习
    • 任务:学生信息排序,先按性别升序,再按年龄降序

一、实战概述

  • 在信息爆炸的时代,数据处理与分析的重要性日益凸显。MapReduce作为一种强大的分布式计算模型,以其高效并行处理能力解决了大规模数据集的处理难题。本次实践教程,我们将通过一个具体的任务——学生信息排序,深入浅出地引导大家掌握MapReduce的基本原理和应用。从数据准备到实现步骤,再到拓展练习,我们将一起领略MapReduce的强大魅力,揭示其在大数据处理中的关键作用。

  • 本教程将通过Hadoop MapReduce实现学生信息排序任务。首先,启动Hadoop服务,创建sortstudent目录和包含学生信息的student.txt文件,然后将其上传到HDFS的/sortstudent/input目录。接着,创建Maven项目SortStudent,添加hadoopjunit依赖,配置日志属性文件。在net.hw.mr包下创建Student类实现序列化比较接口,设置性别升序、年龄降序的比较规则。随后,创建StudentMapperStudentReducer类进行数据处理和排序。在StudentDriver类中设置作业配置并运行。拓展练习中,我们将修改Student类的比较规则以实现性别升序、年龄降序排序,最后重新运行StudentDriver查看结果。

二、提出任务

  • 学生表,包含五个字段(姓名、性别、年龄、手机、专业),有8条记录
    在这里插入图片描述
  • 使用MR,学生信息按年龄降序排列结果
    在这里插入图片描述

三、完成任务

(一)准备数据

  • 启动hadoop服务
    在这里插入图片描述

1、在虚拟机上创建文本文件

  • 创建sortstudent目录,在里面创建student.txt文件
    在这里插入图片描述

2、上传文件到HDFS指定目录

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

(二)实现步骤

1、创建Maven项目

  • Maven项目 - SortStudent
    在这里插入图片描述
  • 单击【Finish】按钮
    在这里插入图片描述

2、添加相关依赖

  • pom.xml文件里添加hadoopjunit依赖
    在这里插入图片描述
<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.hw.mr包里创建Student
    在这里插入图片描述
  • 为了让学生按照年龄排序,需要让学生实体类实现一个序列化可比较接口 - WritableComparable,这个接口有三个抽象方法要我们去实现。
    在这里插入图片描述
package net.hw.mr;

import org.apache.hadoop.io.WritableComparable;

import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;

/**
 * 功能:学生实体类
 *      实现序列化可比较接口
 * 作者:华卫
 * 日期:2022年12月17日
 */
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;
    }

    @Override
    public 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.hw.mr里创建StudentMapper
    在这里插入图片描述
package net.hw.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;

/**
 * 功能:学生映射器类
 * 作者:华卫
 * 日期:2022年12月17日
 */
public class StudentMapper extends Mapper<LongWritable, Text, Student, NullWritable> {
    @Override
    protected 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());
    }
}

5、创建学生归并器类

  • net.hw.mr包里创建StudentReducer
    在这里插入图片描述
package net.hw.mr;

import org.apache.hadoop.io.NullWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer;

import java.io.IOException;

/**
 * 功能:学生归并器类
 * 作者:华卫
 * 日期:2022年12月17日
 */
public class StudentReducer extends Reducer<Student, NullWritable, Text, NullWritable> {
    @Override
    protected 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());
    }
}

6、创建学生驱动器类

  • net.hw.mr包里创建StudentDriver
    在这里插入图片描述
package net.hw.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;

/**
 * 功能:学生驱动器类
 * 作者:华卫
 * 日期:2022年12月17日
 */
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);
        }
    }
}

7、启动学生驱动器类,查看结果

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

四、拓展练习

任务:学生信息排序,先按性别升序,再按年龄降序

  • 运行结果,如下图所示
    在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

OPNET Modeler帮助文档的打开方式

前面有篇文章修改OPNET帮助文档的默认打开浏览器 & 给Edge浏览器配置IE Tab插件已经提到了打开OPNET Modeler打开帮助文档的方法&#xff0c;有时候打开时会显示如下。 界面中没有什么内容加载出来&#xff01;我是在Google浏览器中打开的&#xff0c;其他的浏览器也是一样…

为何多参数遥测终端机成为了当今智能化监测领域的核心工具?

近年来&#xff0c;政府出台了一系列政策&#xff0c;加强了水文/水资源监测和管理的力度&#xff0c;推动了智能化监测技术的发展。根据国家统计局的数据&#xff0c;我国水文/水资源监测站点数量不断增加&#xff0c;监测范围不断扩大&#xff0c;监测数据的质量和精度也不断…

深入了解队列:探索FIFO数据结构及队列

之前介绍了栈&#xff1a;探索栈数据结构&#xff1a;深入了解其实用与实现&#xff08;c语言实现栈&#xff09; 那就快马加鞭来进行队列内容的梳理。队列和栈有着截然不同的工作方式&#xff0c;队列遵循先进先出&#xff08;FIFO&#xff09;的原则&#xff0c;在许多场景下…

共享目录防火墙

导语&#xff1a; 为什么需要配置文件夹共享功能&#xff1f; 我们在工作和生活中经常有需要将自己的文件复制给他人或者将他人的文件复制过来的需求。 有时候我们使用u盘&#xff0c;有时候我们使用qq或者飞秋等软件&#xff0c;但是u盘和软件并不是万能的&#xff0c;比如没…

(10)Linux冯诺依曼结构操作系统的再次理解

&#x1f4ad; 前言&#xff1a;本章我们首先会明确冯诺依曼体系结构的概念&#xff0c;旨在帮助大家理解体系结构在硬件角度去理解数据流走向的问题。理解完之后我们再去谈操作系统、更多有关操作系统的细节&#xff0c;着重谈谈操作系统概念与定位、操作系统是如何去做管理的…

聚观早报 |吉利银河E8将上市;三星Galaxy S24将登场

聚观早报每日整理最值得关注的行业重点事件&#xff0c;帮助大家及时了解最新行业动态&#xff0c;每日读报&#xff0c;就读聚观365资讯简报。 整理丨Cutie 12月26日消息 吉利银河E8将上市 三星Galaxy S24将登场 哪吒L内饰曝光 苹果首款MR头显正量产 IEEE全球研究报告 …

使用防火墙是否可以应对DDoS攻击?

很多游戏行业公司对网络安全不够了解&#xff0c;觉得装个防火墙就可以万事大吉了。实际上使用防火墙确实是解决DDoS攻击问题的一种有效方法&#xff0c;一些更先进的防火墙还可以采用其他防御措施&#xff0c;例如:深度包检测、行为分析、人工智能等&#xff0c;来识别和防御各…

Zookeeper-一致性协议ZAB

ZAB协议介绍 ZAB 协议全称&#xff1a;Zookeeper Atomic Broadcast&#xff08;Zookeeper 原子广播协议&#xff09;。 Zookeeper 是一个为分布式应用提供高效且可靠的分布式协调服务。在解决分布式一致性方面&#xff0c;Zookeeper 并没有使用 Paxos &#xff0c;而是采用了…

《PCI Express体系结构导读》随记 —— 第I篇 第1章 PCI总线的基本知识(3)

接前一篇文章&#xff1a;《PCI Express体系结构导读》随记 —— 第I篇 第1章 PCI总线的基本知识&#xff08;2&#xff09; 1.1 PCI总线的组成 如前文所述&#xff0c;PCI总线作为处理器系统的本地总线&#xff0c;是处理器系统的一个组成部件。因此&#xff0c;讲述PCI总线的…

​ iOS技术博客:App备案指南

&#x1f4dd; 摘要 本文介绍了移动应用程序&#xff08;App&#xff09;备案的重要性和流程。备案是规范App开发和运营的必要手段&#xff0c;有助于保护用户权益、维护网络安全和社会秩序。为了帮助开发者更好地了解备案流程&#xff0c;本文提供了一份最新、最全、最详的备…

分布式训练通信NCCL之Ring-Allreduce详解

&#x1f380;个人主页&#xff1a; https://zhangxiaoshu.blog.csdn.net &#x1f4e2;欢迎大家&#xff1a;关注&#x1f50d;点赞&#x1f44d;评论&#x1f4dd;收藏⭐️&#xff0c;如有错误敬请指正! &#x1f495;未来很长&#xff0c;值得我们全力奔赴更美好的生活&…

PostgreSQL 可观测性最佳实践

简介 软件简述 PostgreSQL 是一种开源的关系型数据库管理系统 (RDBMS)&#xff0c;它提供了许多可观测性选项&#xff0c;以确保数据库的稳定性和可靠性。 可观测性 可观测性&#xff08;Observability&#xff09;是指对数据库状态和操作进行监控和记录&#xff0c;以便在…

【Linux系统基础】(3)在Linux上部署运维监控Zabbix和Grafana

目录 运维监控Zabbix部署简介安装安装前准备 - Mysql安装Zabbix Server 和 Zabbix Agenta. 安装Zabbix yum库b. 安装Zabbix Server、前端、Agentc. 初始化Mysql数据库d. 为Zabbix Server配置数据库e. 配置Zabbix的PHP前端 配置zabbix 前端&#xff08;WEB UI&#xff09; 运维监…

HTML代码全解析

HTML代码全解析实例解析 <!DOCTYPE html> 声明为 HTML5 文档<html> 元素是 HTML 页面的根元素<head> 元素包含了文档的元&#xff08;meta&#xff09;数据&#xff0c;如 <meta charset"utf-8"> 定义网页编码格式为 utf-8。<title> 元…

计算机毕业设计 基于SpringBoot的高校宣讲会管理系统的设计与实现 Java实战项目 附源码+文档+视频讲解

博主介绍&#xff1a;✌从事软件开发10年之余&#xff0c;专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精…

hash路由和history路由的区别

当我们构建前端应用时&#xff0c;路由是一个重要的概念。它允许我们在不刷新整个页面的情况下&#xff0c;根据URL的变化来加载不同的内容。在前端开发中&#xff0c;有两种常见的路由实现方式&#xff1a;哈希路由&#xff08;Hash Routing&#xff09;和历史路由&#xff08…

技术合集|企业AI应用落地的关键问题和应对方法

目录 一、生成式AI助力数字化转型的关键 二、用大模型来做什么 三、AI应用如何落地 四、写在最后 2022年11月&#xff0c;OpenAI正式推出ChatGPT&#xff0c;短短一年的时间里&#xff0c;人类被迫重温了文字语言在人类文明中的重要作用——承载着一切的思维表达与沟通实现…

java毕业设计—vue+springboot影院售票及电影管理系统

1&#xff0c;项目背景 目的&#xff1a;本课题主要目标是设计并能够实现一个基于web网页的电影院购票选座系统&#xff0c;整个网站项目使用了B/S架构&#xff0c;基于vue和SpringBoot框架下开发&#xff1b;管理员通过后台管理系统实现管理影院信息&#xff0c;电影信息&…

Node.js-模块与包

1. 模块 1.1 模块化的基本概念 1.2 模块化规范 2.Node.js中的模块化 2.1 Node.js中的模块化分类 2.2 加载模块 2.3 Node.js中的模块作用域 2.4 向外共享模块作用域的成员 2.4.1 module对象 2.4.2 module.exports对象 2.4.3 共享成员的注意点 2.4.4 exports对象 2.5 Node.js中…

介绍一下我本地使用的截图工具 PixPin

介绍一下我本地使用的截图工具 PixPin 0. 背景1. PixPin 安装文件下载2. PixPin 安装3. PixPin 简单配置4. PixPin 使用 0. 背景 截图是工作上的经常性需求&#xff0c;一个好的截图工具会大大提高我们的工作效率。 一直以来&#xff0c;非常喜欢微信自带的截图功能&#xff…
最新文章