大数据 | 实验一:大数据系统基本实验 | MapReduce 初级编程

news2024/11/18 18:18:35

文章目录

  • 📚实验目的
  • 📚实验平台
  • 📚实验内容
    • 🐇编程实现文件的合并和去重
    • 🐇编程实现对输入文件的排序
    • 🐇对指定的表格进行信息挖掘

📚实验目的

1)通过实验掌握基本的 MapReduce 编程方法。

2)掌握用 MapReduce 解决一些常见的数据处理问题,包括数据去重、数据排序和数据挖掘等。

📚实验平台

1)操作系统:Linux;

2)Hadoop 版本:3.2.2;

📚实验内容

🐇编程实现文件的合并和去重

在这里插入图片描述
在这里插入图片描述

package hdfs; 
import java.io.IOException; 
import org.apache.hadoop.conf.Configuration; 
import org.apache.hadoop.fs.Path; 
import org.apache.hadoop.io.IntWritable; 
import org.apache.hadoop.io.Text; 
import org.apache.hadoop.mapreduce.Job; 
import org.apache.hadoop.mapreduce.Mapper; 
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 Merge 
{ 
    //这段代码输出的结果是原始输入数据的全部内容作为key,value为空的键值对。
 	public static class Map extends Mapper<Object, Text, Text, Text>
    { 
        //在Map类中定义了一个静态变量text,并将其类型设置为Text。
 	 	private static Text text = new Text(); 
        //map方法中的参数分别表示输入数据的键、值和上下文对象
        //上下文对象可以用于向输出写入数据。
  		public void map(Object key, Text value, Context context) throws IOException,InterruptedException
        { 
            //将输入的value数据赋值给text变量
   			text = value; 
            //text作为key,一个空的Text对象作为value输出。
   			context.write(text, new Text("")); 
  		} 
    } 
  
 	//简单地将Mapper输出的所有键值对的key提取出来作为Reducer的输出。 
 	public static class Reduce extends Reducer<Text, Text, Text, Text>
    {   
        // reduce方法中的参数分别表示输入数据的键、值集合和上下文对象
        //上下文对象可以用于向输出写入数据。
        public void reduce(Text key, Iterable<Text> values, Context context ) throws IOException,InterruptedException
        { 
            //将输入的key作为key,一个空的Text对象作为value输出
   			context.write(key, new Text("")); 
            //因为这里没有对values集合进行处理
            //所以values中的数据会被忽略掉,只有输入的key被输出。
  		}  
    } 
  
 	public static void main(String[] args) throws Exception
    {    
 		//首先创建一个Configuration对象,用于存储Hadoop集群中的一些配置信息。
  		Configuration conf = new Configuration(); 
        //设置Hadoop集群的默认文件系统为hdfs://localhost:9000。
		conf.set("fs.default.name","hdfs://localhost:9000"); 
        
        //接着检查输入参数是否正确
        //需要传入两个参数,第一个是输入数据路径,第二个是输出结果路径。
  		String[] otherArgs = new String[]{"input","output"}; 
  		if (otherArgs.length != 2) 
        { //如果参数不满足要求,则输出错误提示并退出程序。
  		 	System.err.println("Usage: wordcount <in><out>"); 
   			System.exit(2); 
   		} 
        
        //创建一个Job对象,使用"Merge and duplicate removal"作为任务名称。
  		Job job = Job.getInstance(conf,"Merge and duplicate removal"); 
        //使用Merge类的class对象来设置job所在的jar包。
        job.setJarByClass(Merge.class);   
        //设置Map类作为Mapper
        job.setMapperClass(Map.class);   
        //设置Reduce类为Combiner和Reducer。
        job.setCombinerClass(Reduce.class);   
        job.setReducerClass(Reduce.class); 
        //设置输入数据和输出结果的键值类型。
  		job.setOutputKeyClass(Text.class);   
        job.setOutputValueClass(Text.class); 
        //设置输入数据路径。
  		FileInputFormat.addInputPath(job, new Path(otherArgs[0])); 
        //设置输出结果路径
  		FileOutputFormat.setOutputPath(job, new Path(otherArgs[1]));
        //提交任务并等待任务执行完成,根据执行状态返回0或1表示任务执行成功或失败。
  		System.exit(job.waitForCompletion(true) ? 0 : 1); 
 	} 
}

🐇编程实现对输入文件的排序

在这里插入图片描述

在这里插入图片描述

package hdfs; 
import java.io.IOException; 
import org.apache.hadoop.conf.Configuration; 
import org.apache.hadoop.fs.Path; 
import org.apache.hadoop.io.IntWritable; 
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 MergeSort 
{ 
    //这段代码将输入的文本数据中的每一个整数作为键,对应的出现次数设置为1作为值
 	public static class Map extends Mapper<Object, Text, IntWritable, IntWritable>
    { 
		private static IntWritable data = new IntWritable(); 
  		public void map(Object key, Text value, Context context) throws 
IOException,InterruptedException
        { 
            //输入的key是偏移量,value是那个数值
            //首先将输入数据从Text类型转换为String类型,并赋值给text变量。
   			String text = value.toString(); 
            //然后将text转换为Int类型,并将其封装到IntWritable对象中,赋值给data变量。
            data.set(Integer.parseInt(text)); 
            //将data作为输出key,new IntWritable(1)作为输出值value写入上下文中
   			context.write(data, new IntWritable(1)); 
  		}  
    } 
    
    //在进入reduce之前会有一个partition的过程,但因为我们现在电脑配置的datenode只有一个,所以最后其实都会就进入那一个dateNode。
    public static class Partition extends Partitioner<IntWritable, IntWritable>
    {   
        public int getPartition(IntWritable key, IntWritable value, int num_Partition)
        { 
            //getPartition方法的三个参数分别表示输入键、输入值和分区数。
   			int Maxnumber = 65223;
            //首先定义了一个最大数字Maxnumber,并根据分区数计算出每个分区的边界bound
            //即将Maxnumber均匀地分为num_Partition个部分
   			int bound = Maxnumber/num_Partition+1;   
            //接着获取当前输入键的整数值keynumber
            int keynumber = key.get();    
            for (int i = 0; i<num_Partition; i++)
            {     
                //然后遍历所有分区,通过比较keynumber与边界值的大小关系,找到它应该属于的分区。
                if(keynumber<bound * (i+1) && keynumber>=bound * i)
                { 
                    //如果找到了对应的分区,则返回该分区的编号i;
                    //否则,如果在所有分区中都没有找到对应的分区,则返回-1,表示出错。
     				return i;     
                } 
   			} 
   			return -1; 
  		}  
    }   
    
    //对Map类输出的中间结果按键值排序,为每个键值对添加一个唯一的序号,并将排序后的结果作为最终输出结果。
    //在本例中,输出结果是一个序号与整数对应的列表。
 	public static class Reduce extends Reducer<IntWritable, IntWritable, IntWritable, IntWritable>
    { 
        //Reduce的泛型参数分别表示输入键、输入值、输出键和输出值的类型。
  		private static IntWritable line_num = new IntWritable(1); 
  		public void reduce(IntWritable key, Iterable<IntWritable> values, Context context) throws IOException,InterruptedException
        {   
            //遍历Iterable<IntWritable>类型的values参数,将其按照key值排序后输出。
            for(IntWritable val : values)
            {     
                //这里的排序是自动排序
                //使用context.write方法将line_num作为输出键,key作为输出值写入上下文中。
                context.write(line_num, key); 
                //每输出一个键值对,line_num的值就加1,以保证输出的键值对具有唯一的序号。
        		line_num = new IntWritable(line_num.get() + 1); 
       		}  
            //这里for循环的意义就是避免去重,让key相同的都能遍历输出。
        }  
    } 
    
 	public static void main(String[] args) throws Exception
    { 
  		Configuration conf = new Configuration();
		conf.set("fs.default.name","hdfs://localhost:9000"); 
 		String[] otherArgs = new String[]{"input","output"}; 
  		if (otherArgs.length != 2) 
        { 
  		 	System.err.println("Usage: wordcount <in><out>"); 
   			System.exit(2); 
   		} 
		Job job = Job.getInstance(conf,"Merge and sort");   
        //设置运行的主类为MergeSort。
        job.setJarByClass(MergeSort.class); 
        //设置Mapper类为Map。
        job.setMapperClass(Map.class);
        //设置Reducer类为Reduce。
        job.setReducerClass(Reduce.class);
        //设置Partitioner类为Partition。
        job.setPartitionerClass(Partition.class);   
        //设置输出键类型为IntWritable。
        job.setOutputKeyClass(IntWritable.class); 
        //设置输出值类型为IntWritable。
        job.setOutputValueClass(IntWritable.class); 
        //使用addInputPath()方法将输入路径添加到任务中
        FileInputFormat.addInputPath(job, new Path(otherArgs[0])); 
        //使用setOutputPath()方法将输出路径设置到任务中。
  		FileOutputFormat.setOutputPath(job, new Path(otherArgs[1])); 
        //使用waitForCompletion()方法启动任务,并等待任务完成。
        //如果任务执行成功,则返回0;否则,返回1。在最后使用System.exit()方法退出程序。
  		System.exit(job.waitForCompletion(true) ? 0 : 1);   
    } 
}

🐇对指定的表格进行信息挖掘

在这里插入图片描述

package hdfs; 
import java.io.IOException; 
import java.util.*; 
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path; 
import org.apache.hadoop.io.IntWritable; 
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
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 map 
{  
    //用于输出标题
    public static int time = 0;
    //“child_name”、“parent_name”和“relation_type”作为键值对输出到Context对象中。
 	public static class Map extends Mapper<Object, Text, Text, Text>
    { 
		public void map(Object key, Text value, Context context) 
            throws IOException,InterruptedException
        { 
   			String child_name = new String(); 
   			String parent_name = new String(); 
   			String relation_type = new String();    
			String line = value.toString();    
            int i = 0; 
   			while(line.charAt(i) != ' ')
            {//将输入的每一行文本数据以空格为分隔符
                i++; 
   			} 
            //将第一个部分作为子节点名称,第二个部分作为父节点名称,以及一个关系类型组成的字符串
   			String[] values = {line.substring(0,i),line.substring(i+1)};    
            if(values[0].compareTo("child") != 0)
            {   
                //如果“child_name”不等于“child”(就不是标题)    
                //key是父亲,1
				child_name = values[0];     
				parent_name = values[1];     
				relation_type = "1";
    			context.write(new Text(values[1]), 
				new Text(relation_type+"+"+child_name+"+"+parent_name));                
                //key是孩子,2
    			relation_type = "2"; 
    			context.write(new Text(values[0]),  
                new Text(relation_type+"+"+child_name+"+"+parent_name));  
            }  
        }   
    } 

public static class Reduce extends Reducer<Text, Text, Text, Text>
    { 
  		public void reduce(Text key, Iterable<Text> values,Context context) 
            throws IOException,InterruptedException
        { 
  	 		if(time == 0)
            {   
                //用于标题
    			context.write(new Text("grand_child"), new Text("grand_parent")); 
    			time++; 
   			} 
   			int grand_child_num = 0; //用于在数组里插入
   			String grand_child[] = new String[10];//孙辈的数组 
            int grand_parent_num = 0; //用于在数组里插入
   			String grand_parent[]= new String[10];//祖辈的数组 
            Iterator ite = values.iterator(); 
   			while(ite.hasNext())
            { 
    			String record = ite.next().toString(); 
   				int len = record.length();     
                int i = 2; //i=0是relation_type,i=1是“+”
    			if(len == 0) continue; 
    			char relation_type = record.charAt(0);   
 				String child_name = new String(); 
				String parent_name = new String(); 
    			while(record.charAt(i) != '+')
                { //child,从2开始
     				child_name = child_name + record.charAt(i); 
    	 			i++; 
    			} 
    			i=i+1; //一个加号
				while(i<len)
                { //"childname+"后面的内容
     				parent_name = parent_name+record.charAt(i); 
     				i++; 
    			} 
				if(relation_type == '1')
                { //父亲,就取孩子的名字,就是孙辈的名字
                     grand_child[grand_child_num] = child_name; 
                     grand_child_num++; 
   	 			} 
    			else
                {//孩子,就取父亲的名字,就是祖辈的名字
  	 				grand_parent[grand_parent_num] = parent_name; 
                    grand_parent_num++; 
    			}    
            } 
   			if(grand_parent_num != 0 && grand_child_num != 0 )//全排列
            { 
 				for(int m = 0;m<grand_child_num;m++)
                {      
                    for(int n=0;n<grand_parent_num;n++)
                    { 
      					context.write(new Text(grand_child[m]), new Text(grand_parent[n]));
                        //对每一行进行reduce
      				}  
                }   
            }  
        }  
    } 
    
 	public static void main(String[] args) throws Exception
    { 
  		Configuration conf = new Configuration(); 
		conf.set("fs.default.name","hdfs://localhost:9000"); 
  		String[] otherArgs = new String[]{"input","output"};
  		if (otherArgs.length != 2) 
        { 
   			System.err.println("Usage: wordcount <in><out>"); 
			System.exit(2); 
   		} 
		Job job = Job.getInstance(conf,"Single table join");
        //设置运行的主类为map。
        job.setJarByClass(map.class); 
        //设置Mapper类为Map。
        job.setMapperClass(Map.class);
        //设置Reducer类为Reduce。
        job.setReducerClass(Reduce.class); 
        //设置输入数据和输出结果的键值类型。
        job.setOutputKeyClass(Text.class);   
        job.setOutputValueClass(Text.class); 
        //设置输入数据路径。
  		FileInputFormat.addInputPath(job, new Path(otherArgs[0])); 
        //设置输出结果路径。
  		FileOutputFormat.setOutputPath(job, new Path(otherArgs[1])); 
        //使用waitForCompletion()方法启动任务,并等待任务完成。
        //如果任务执行成功,则返回0;否则,返回1。在最后使用System.exit()方法退出程序。
  		System.exit(job.waitForCompletion(true) ? 0 : 1); 
	} 
}

补充学习博客:MapReduce编程规范及示例编写

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

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

相关文章

警惕“Money Message”勒索软件!数据安全不容忽视

近段时间&#xff0c;出现了一个名为“Money Message”的新型勒索软件&#xff0c;他们利用Money Message 病毒加密文件并以此向受害者勒索巨额赎金。 Money Message勒索软件是用 C编写&#xff0c;包含一个嵌入式JSON 配置文件&#xff0c;用于确定设备的加密方式。加密设备后…

小红书内容种草,曝光渠道分析总结

这是一个内容为王的时代&#xff0c;也是一个内容爆炸的时代。想要在以分享特色的小红书平台&#xff0c;实现内容种草&#xff0c;迅速出圈。今天来马文化传媒就从实操的角度&#xff0c;为大家带来小红书内容种草&#xff0c;曝光渠道分析总结的各种干货&#xff01; 一、什…

关于图形界面Pyqt与QT的区别选择

关于图像界面&#xff08;GUI&#xff09;想必大家都并不陌生&#xff0c;想要将一段已经完善的功能列表进行可视化操作并且具有一定的操作空间&#xff0c;将功能可视化必不可少&#xff0c;一个好的可视化工具不仅可以集成一系列小的文件功能&#xff0c;还能将不同方法之间的…

ubuntu基本环境配置及mysql8.0.32和mysql workbench安装

ubuntu基本环境配置 文章目录ubuntu基本环境配置各种依赖包下载地址一、使用root账号进行远程连接二、防火墙相关设置2.1启用2.2开放和关闭端口数据库mysql安装(8.0.32)工具mysqlworkbench(8.0.32)各种依赖包下载地址 http://cn.archive.ubuntu.com/ubuntu/pool/main/liba/lib…

【1019. 链表中的下一个更大节点】

来源&#xff1a;力扣&#xff08;LeetCode&#xff09; 描述&#xff1a; 给定一个长度为 n 的链表 head 对于列表中的每个节点&#xff0c;查找下一个 更大节点 的值。也就是说&#xff0c;对于每个节点&#xff0c;找到它旁边的第一个节点的值&#xff0c;这个节点的值 严…

三天吃透Redis八股文

Redis连环40问&#xff0c;绝对够全&#xff01; Redis是什么&#xff1f; Redis&#xff08;Remote Dictionary Server&#xff09;是一个使用 C 语言编写的&#xff0c;高性能非关系型的键值对数据库。与传统数据库不同的是&#xff0c;Redis 的数据是存在内存中的&#xf…

java调用python动态生成光电雷达图

一、编写java调用程序 //http://localhost:8945/api/ExecPy/ExecPyPollutionRadarMap ApiOperation(value "ExecPy") GetMapping(value "/ExecPyPollutionRadarMap") public String ExecPyPollutionRadarMap() {String scriptpath"F:\\demo\\Radar…

如何驱动模拟舵机-Controller 1.0b软件的使用

1.支持平台 win10、win7 win10打开Controller 1.0.exe即可运行&#xff1b;win7需要先安装Controller1.0b资料包\NetFarmwork文件夹中的.net框架组件。 2.电子硬件 我们用以下硬件为例来讲解Controller 1.0b软件的使用&#xff1a; 主控板 Basra主控板&#xff08;兼容Arduino…

selenium自动化测试面试题【含答案】

目录 1、selenium中如何判断元素是否存在&#xff1f; 2、selenium中hidden或者是display &#xff1d; none的元素是否可以定位到&#xff1f; 3、selenium中如何保证操作元素的成功率&#xff1f;也就是说如何保证我点击的元素一定是可以点击的&#xff1f; 4、如何提高s…

谷歌浏览器安装插件(从 Edge 浏览器里获取插件)

前言&#xff1a; 因为谷歌插件 商店&#xff0c;国内&#xff08;不科学上网&#xff09;是无法访问的&#xff0c;所以 要安装插件就得 通过各种途径 下载后 解压&#xff0c;然后安装。 谷歌浏览器下载、安装插件的方式 方式一&#xff1a;自行 百度下载压缩包&#xff0…

win10安装telnet服务器(开启端口,开启telnet客户端后依旧显示:无法打开到主机的连接,在端口xxxx连接失败)

前言 注&#xff1a;我使用telnet的根本原因是想测试端口是否通&#xff0c;因为要使用花生壳&#xff0c; 而之所以会显示 启telnet客户端后依旧显示&#xff1a;无法打开到主机的连接&#xff0c;在端口xxxx连接失败 错误&#xff0c;本质原因是&#xff1a; 1、你没有teln…

tensorflow深度神经网络实现鸢尾花分类

tensorflow深度神经网络实现鸢尾花分类 本文目录tensorflow深度神经网络实现鸢尾花分类获取数据集相关库的导入数据展示和划分对标签值进行热编码模型搭建使用Sequential模型搭建模型模型训练对训练好的模型进行评估使用model模型搭建模型对训练好的模型进行评估损失函数优化方…

使用golang连接kafka

1 下载&#xff0c;配置&#xff0c;启动 kafka 下载链接 配置修改 在config目录下的server文件和zookeeper文件&#xff0c;其中分别修改kafka的日志保存路径和zookeeper的数据保存路径。 启动kafka 先启动kafka自带的zookeeper&#xff0c;在kafka的根目录下打开终端&a…

百模大战,谁是下一个ChatGPT?

“不敢下手&#xff0c;现在中国还没跑出来一家绝对有优势的大模型&#xff0c;上层应用没法投&#xff0c;担心押错宝。”投资人Jucy&#xff08;化名&#xff09;向光锥智能表示&#xff0c;AI项目看得多、投的少是这段时间的VC常态。 ChatGPT点燃AI大爆炸2个月中&#xff0…

为什么工控行业生意越来越难做了?

前段时间跟几个做工业品销售的朋友聚了一下&#xff0c;大家都说去年一年挺难的&#xff0c;有些甚至想把小店关了。为什么现在工业品领域越来越难做了呢&#xff1f;今天也想给大家说一说我的一些看法。 以前的工控生意相对现在来说较为有限和封闭&#xff0c;技术上也没有现今…

Android 大图检测插件的落地

作者&#xff1a;layz4android 在实际的项目开发中&#xff0c;引入图片的方式基本可以分为两种&#xff1a;本地图片和云端图片&#xff0c;对于云端图片来说&#xff0c;可以动态地配置图片的大小&#xff0c;如果服务端的伙伴下发的图片很大导致程序异常&#xff0c;那么可以…

前端视角-https总结

1.http存在的问题 1.1可能被窃听 HTTP 本身不具备加密的功能,HTTP 报文使用明文方式发送互联网是由联通世界各个地方的网络设施组成,所有发送和接收经过某些设备的数据都可能被截获或窥视。(例如TCP/IP抓包工具:Wireshark),即使经过加密处理,也会被窥视是通信内容,只是可能很…

在 Flutter 多人视频通话中实现虚拟背景、美颜与空间音效

前言 在之前的「基于声网 Flutter SDK 实现多人视频通话」里&#xff0c;我们通过 Flutter 声网 SDK 完美实现了跨平台和多人视频通话的效果&#xff0c;那么本篇我们将在之前例子的基础上进阶介绍一些常用的特效功能&#xff0c;包括虚拟背景、色彩增强、空间音频、基础变声…

HBase高手之路4-Shell操作

文章目录HBase高手之路3—HBase的shell操作一、hbase的shell命令汇总二、需求三、表的操作1&#xff0e;进入shell命令行2&#xff0e;创建表3&#xff0e;查看表的定义4&#xff0e;列出所有的表5&#xff0e;删除表1)禁用表2)启用表3)删除表四、数据的操作1&#xff0e;添加数…

TensorFlow 深度学习实战指南:1~5 全

原文&#xff1a;Hands-on Deep Learning with TensorFlow 协议&#xff1a;CC BY-NC-SA 4.0 译者&#xff1a;飞龙 本文来自【ApacheCN 深度学习 译文集】&#xff0c;采用译后编辑&#xff08;MTPE&#xff09;流程来尽可能提升效率。 不要担心自己的形象&#xff0c;只关心如…