MR案例(3):计算学生成绩(总分和平均分)

news2024/11/25 5:05:56

文章目录

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


一、 任务目标

  • 利用MR框架,计算每个同学的总分与平均分

1. 准备数据

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

  • 创建/calcscore/input目录,执行命令:hadoop fs -mkdir -p /calcscore/input
    在这里插入图片描述

  • 将文本文件score.txt,上传到HDFS的/calcscore/input目录,执行命令:hadoop fs -put score.txt /calcscore/input
    在这里插入图片描述

二、实行任务

1. 创建Maven项目

在这里插入图片描述

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/calcscore.log
log4j.appender.logfile.layout=org.apache.log4j.PatternLayout
log4j.appender.logfile.layout.ConversionPattern=%d %p [%c] - %m%n

4. 创建成绩映射器类

  • 在net.kox.mr里创建ScoreMapper类
package net.kox.mr;

import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper;

import java.io.IOException;

public class ScoreMapper extends Mapper <LongWritable, Text, Text, IntWritable>{
    @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].trim();
        // 遍历各科成绩
        for (int i = 1; i < fields.length; i++) {
            // 获取成绩
            int score = Integer.parseInt(fields[i].trim());
            // 写入<姓名,成绩>键值对
            context.write(new Text(name), new IntWritable(score));
        }
    }
}

5. 创建成绩驱动器类

  • 在net.kox.mr包里创建ScoreDriver类
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.IntWritable;
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 ScoreDriver {
    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(ScoreDriver.class);

        // 设置Mapper类
        job.setMapperClass(ScoreMapper.class);
        // 设置map任务输出键类型
        job.setMapOutputKeyClass(Text.class);
        // 设置map任务输出值类型
        job.setMapOutputValueClass(IntWritable.class);

        // 定义uri字符串
        String uri = "hdfs://master:9000";
        // 创建输入目录
        Path inputPath = new Path(uri + "/calcscore/input");
        // 创建输出目录
        Path outputPath = new Path(uri + "/calcscore/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);
        }
    }
}

6. 启动成绩驱动器类,查看结果

  • 运行ScoreDriver类
    在这里插入图片描述

7. 创建成绩归并器类

  • 在net.kox.mr包里创建ScoreReducer类
package net.kox.mr;

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

import java.io.IOException;
import java.text.DecimalFormat;

public class ScoreReducer extends Reducer<Text, IntWritable, Text, NullWritable> {
    @Override
    protected void reduce(Text key, Iterable<IntWritable> values, Context context)
            throws IOException, InterruptedException {
        // 声明变量
        int count = 0; // 科目数
        int sum = 0; // 总分
        double avg = 0; // 平均分
        // 遍历迭代器计算总分
        for (IntWritable value : values) {
            count++; // 科目数累加
            sum += value.get(); // 总分累加
        }
        // 计算平均分
        avg = sum * 1.0 / count;
        // 创建小数格式对象
        DecimalFormat df = new DecimalFormat("#.#");
        // 拼接每个学生总分与平均分成绩信息
        String scoreInfo = "(" + key + "," + sum + "," + df.format(avg) + ")";
        // 写入键值对
        context.write(new Text(scoreInfo), NullWritable.get());
    }
}

8. 修改成绩驱动器类

  • 设置Reducer类及其输出键值类型
    在这里插入图片描述
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.IntWritable;
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 ScoreDriver {
    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(ScoreDriver.class);

        // 设置Mapper类
        job.setMapperClass(ScoreMapper.class);
        // 设置map任务输出键类型
        job.setMapOutputKeyClass(Text.class);
        // 设置map任务输出值类型
        job.setMapOutputValueClass(IntWritable.class);

        // 设置Reducer类
        job.setReducerClass(ScoreReducer.class);
        // 设置reduce任务输出键类型
        job.setOutputKeyClass(Text.class);
        // 设置reduce任务输出值类型
        job.setOutputValueClass(NullWritable.class);

        // 定义uri字符串
        String uri = "hdfs://master:9000";
        // 创建输入目录
        Path inputPath = new Path(uri + "/calcscore/input");
        // 创建输出目录
        Path outputPath = new Path(uri + "/calcscore/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);
        }
    }
}

9. 启动成绩驱动器列,查看结果

在这里插入图片描述

  • 利用HDFS Shell命令查看结果文件内容,执行命令:hadoop fs -cat /calcscore/output/*
    在这里插入图片描述

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

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

相关文章

艾美捷利妥昔单抗Rituximab参数及应用

艾美捷利妥昔单抗Rituximab背景&#xff1a; 利妥昔单抗是一种针对CD20抗原的基因工程嵌合鼠/人单克隆IgG1κ抗体。利妥昔单抗的分子量约为145 kD。利妥昔单抗由哺乳动物细胞&#xff08;中国仓鼠卵巢&#xff09;产生。 艾美捷利妥昔单抗Rituximab基本参数&#xff1a; 中文…

Java+SSM流浪猫狗救助领养网站(含源码+论文+答辩PPT等)

项目功能简介: 该项目采用技术&#xff1a; 后端采用SSM框架 前端采用了htmlcssbootstrap框架 MySQL数据库Tomcat服务器&#xff0c;项目含有源码、文档、配套开发软件、软件安装教程、项目发布教程等 项目功能介绍&#xff1a; 项目分为前端和后端两&#xff0c;包含的功能主要…

DBCO-PEG-TPP,二苯并环辛炔-聚乙二醇-磷酸三苯酯,DBCO-PEG磷酸三苯酯

【产品描述】 西安凯新生物科技有限公司供应的&#xff1a;​DBCO-PEG-TPP亲水性聚乙二醇 (PEG) 间隔臂提供了一个长而灵活的连接&#xff0c;磷酸三苯酯为无味、无臭的白色结晶块状或粉末&#xff0c;它不溶于冷水,但可溶于50℃以上的热水中,当溶液温度降低至室温时呈现疏水性…

安装 DbVisualizer pro 10.0.16

DbVisualizer pro 10.0.16 双击安装&#xff0c; 选择下载 JRE运行后 选择 创建 桌面快捷方式 安装成功后 ping 报错无法连接到mysql &#xff0c; 驱动 所致 官方下载最新驱动 MySQL :: Download MySQL Connector/J (Archived Versions)https://downloads.mysql.com/archi…

校园二手书商城源代码基于微信小程序云开发,可在线支付提现,含详细配置教程

校园二手书商城源代码基于微信小程序云开发&#xff0c;可在线支付提现&#xff0c;含详细配置教程 完整代码下载地址&#xff1a;校园二手书商城源代码基于微信小程序云开发 欢迎使用&#xff0c;下面是配置教程 长话短说&#xff0c;下面直接说配置流程 一、小程序端 1…

JZ31. 栈的压入、弹出序列

文章目录1. 题目描述2. 解题思路3. 动图演示4. 代码实现1. 题目描述 题目链接&#xff1a;31. 栈的压入、弹出序列 2. 解题思路 元素入栈指的是把新元素放到栈顶元素的上面&#xff0c;使之成为新的栈顶元素&#xff1b; 元素出栈指的是从一个栈删除元素又称作出栈或退栈&am…

MySQL8.0高级篇(上)-架构与索引

文章目录一、MySQL环境安装与介绍1、MySQL安装1.1 安装前说明1.2 MySQL的Linux版安装1.3 MySQL登录1.4 字符集的相关操作1.5 字符集与比较规则(了解)1.6 请求到响应过程中字符集的变化1.7 SQL大小写规范1.8 sql_mode的合理设置2、MySQL的数据目录2.1 MySQL8的主要目录结构2.2 查…

Batch Normalization批量归一化

批量归一化&#xff08;batch normalization&#xff09;层&#xff0c;它能让较深的神经网络的训练变得更加容易。 对深层神经网络来说&#xff0c;即使输入数据已做标准化&#xff0c;训练中模型参数的更新依然很容易造成靠近输出层输出的剧烈变化。这种计算数值的不稳定性通…

前端基础_事件介绍

事件介绍 下面介绍一下浏览器在请求媒体数据、下载媒体数据、播放媒体数据一直到播放结束这一系列过程中&#xff0c;到底会触发哪些事件。  loadstart事件&#xff1a;浏览器开始请求媒介。  progress事件&#xff1a;浏览器正在获取媒介。  suspend事件&#xff1a;浏览器…

[附源码]计算机毕业设计Python大学生心理测评系统(程序+源码+LW文档)

该项目含有源码、文档、程序、数据库、配套开发软件、软件安装教程 项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等…

(15)目标检测算法之 YOLOv7应用解析

本文翻译自&#xff1a;https://github.com/WongKinYiu/yolov7 YOLOv7 2022年发布&#xff0c;论文链接&#xff1a;YOLOv7: Trainable bag-of-freebies sets new state-of-the-art for real-time object detectors 模型性能如下&#xff1a; 网页端可执行demo&#xff1a;Hu…

分支和循环语句(5)

目录 1、什么是语句&#xff1f; 2、分支语句&#xff08;选择结构&#xff09; 1、if 语句 1、if 语句的语法结构 2、悬空else 3、if书写形式的对比 4、练习 3、switch语句 1、语法形式 2、在switch语句中的 break 3、default子句 4、循环语句 1、while循环 1、…

10个Excel实用操作技巧分享,使用率超高,让你一学就会

学习和工作都能用到的Excel操作技巧&#xff0c;非常简单但是很实用&#xff0c;学会之后你会发现这些技巧的使用率超高&#xff0c;整理之后放在下面了&#xff0c;都是增加工作系效率的好帮手。1.冻结窗格 如果表格记录的数据比较多&#xff0c;我们可以使用【冻结窗格】&…

A. Parsa‘s Humongous Tree(树形DP + 贪心)

Problem - 1528A - Codeforces 两个玩家正在玩一个游戏。他们有一个整数1&#xff0c;2&#xff0c;...&#xff0c;n的排列组合&#xff08;排列组合是一个数组&#xff0c;其中从1到n的每个元素正好出现一次&#xff09;。这个排列组合没有按升序或降序排序&#xff08;即排列…

智能遥测终端机——微功耗设计的物联网网关

一、产品概述 智能遥测终端机是一款采用微功耗设计的物联网网关&#xff0c;采用内置电池组供电&#xff0c;支持对模拟量、开关量、RS485传感器采集并通过NB-IoT或4G通讯方式传输数据。智能遥测终端机支持参数远程升级、远程配置、蓝牙配置等&#xff0c;智能遥测终端机集成高…

1572_AURIX_TC275_SCU中的锁步以及芯片温度采集

全部学习汇总&#xff1a; GreyZhang/g_TC275: happy hacking for TC275! (github.com) 这个是锁步控制寄存器&#xff0c;其实是一个控制以及状态综合的寄存器。可以读取到现在的锁步设置状态&#xff0c;也可以进行锁步的使能。 这个寄存器跟上面这一个页一样&#xff0c;只是…

开发1-5年的Java程序员,该学习哪些知识实现涨薪30K?

工作已经8年有余&#xff0c;这8年里特别感谢技术管理人员的器重&#xff0c;以及同事的帮忙&#xff0c;学到了不少东西。这8年里走过一些弯路&#xff0c;也碰到一些难题&#xff0c;也受到过做为一名开发却经常为系统维护和发布当救火队员的苦恼。遂决定梳理一下自己所学的东…

11_逆向工程

MyBatis的一个主要的特点就是需要程序员自己编写SQL&#xff0c;那么如果表太多的话&#xff0c;难免会很麻烦&#xff0c;所以MyBatis官方提供了一个逆向工程&#xff0c;可以针对单表自动生成MyBatis执行所需要的代码&#xff08;包括mapper.xml&#xff0c;mapper.java&…

数据安全治理笔记

数据安全治理整理概述 数据安全治理不仅局限于组织内部&#xff0c;而是需要一个国家、行业组织、可言机构、企业和个人共同努力完成的课题。因此&#xff0c;应该分别重广义和狭义的角度看待数据安全治理。 广义地说&#xff1a;数据安全治理是在过数据安全战略的知道下&…

状态寄存器传送指令 —— 访问(读写)CPSR寄存器

CPSR寄存器控制着CPU的工作模式和运算状态&#xff0c;出于对CPSR的保护&#xff0c;不允许其他指令来访问CPSR寄存器。 因此&#xff0c;ARM提供了读写指令来操作CPSR寄存器&#xff0c;这两个指令是ARM特有的指令集&#xff0c;因为处理器之间存在一定差异&#xff0c;控制状…