Hadoop_day07学习笔记

本文介绍Hadoop中自定义Writable类的方法,用于处理多于两对Key-Value的情况,并通过示例展示如何实现序列化与反序列化,以及MapReduce作业的具体配置。

一、零散知识

1.序列化:把结构化对象转化为字节流

2.反序列化  序列化的逆过程 把字节流转化为结构化对象

3.序列化格式特点:紧凑:高效使用存储空间。
                            快速:读写数据的额外开销小
                            可扩展:可透明地读取老格式的数据

                            互操作:支持多语言的交互

hadoop的序列化格式 : Writable

4.序列化在分布式环境的两大作用:进程间通信,永久存储。

即节点一  传输文件至节点二 1上消息序列化为二进制流   中间二进制流传输   2上二进制流反序列化为消息

5.很重要

Writable接口, 
是根据 DataInput 和 DataOutput 实现的简单、有效的序列化对象.

MR的任意Key和Value必须实现Writable接口.

MR的任意key必须实现WritableComparable接口

6.hadoop中的数据类型


1~5这种类似于数据库中的varchar()有多少占多少弹性的

二、案例

概述、hadoop最多可以提供两对输入输出的key value对 超出的话该怎么办

所以引入了自定义Writable类  (前面讲过所有的key value都要去实现Writable接口)

package com.myreduce;

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

import org.apache.hadoop.io.Writable;

/**
 * 这是自己定义的一个Writable类
 * 因为hadoop只能提供两个的输入输出的数据操作  而我们要处理四个的超出了负载 所以需要自己定义一个 MapReduce任意的key
 * value都实现了Writable接口(可以查看源码) MapReduce任意的key 都必须实现Writablecomparable
 * 
 * @author zzh
 *
 */
public class Traffic implements Writable {
	private long t1 = 0;
	private long t2 = 0;
	private long t3 = 0;
	private long t4 = 0;

	// 无参构造
	public Traffic() {
	}

	public Traffic(long t1, long t2, long t3, long t4) {
		this.t1 = t1;
		this.t2 = t2;
		this.t3 = t3;
		this.t4 = t4;
	}

	public long getT1() {
		return t1;
	}

	public void setT1(long t1) {
		this.t1 = t1;
	}

	public long getT2() {
		return t2;
	}

	public void setT2(long t2) {
		this.t2 = t2;
	}

	public long getT3() {
		return t3;
	}

	public void setT3(long t3) {
		this.t3 = t3;
	}

	public long getT4() {
		return t4;
	}

	public void setT4(long t4) {
		this.t4 = t4;
	}

	// 实现接口 实现(重写)write和read方法
	public void write(DataOutput out) throws IOException {
		out.writeLong(t1);
		out.writeLong(t2);
		out.writeLong(t3);
		out.writeLong(t4);
	}

	public void readFields(DataInput in) throws IOException {
		this.t1 = in.readLong();
		this.t2 = in.readLong();
		this.t3 = in.readLong();
		this.t4 = in.readLong();
	}

	@Override
	public String toString() {
		return "Traffic [t1=" + t1 + ", t2=" + t2 + ", t3=" + t3 + ", t4=" + t4
				+ "]";
	}

}
package com.myreduce;

import java.io.IOException;

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

/**
 * map阶段
 * @author zzh
 * KEYIN:默认情况下是MapReduce框架所读到的一行文本的偏移量,Long
 * 但是在hadoop中有自己更精简的序列化接口,所以不直接用long而是用LongWritable
 * 
 * VALUE:默认情况下是MapReduce框架所读到的一行文本的内容。String同上 用Text
 * 
 * KEYOUT:是用户自定义逻辑处理写成之后输出数据中的key,String同上Text
 * 
 * VALUEOUT:是用户自定义逻辑处理写成之后输出数据中的value 再此处因为输出四个数据,所以用自定义的Traffic
 */
public class TrafficMapper extends Mapper<LongWritable, Text, Text, Traffic>{
	/*
	 * map阶段的业务逻辑就写在自己定义的map()方法中
	 * 把读入的文件解析成key value对。 对输入的文件每一行解析为key value对
	 * 每个键值对都会调用一次我们定义的map()方法
	 */
	@Override
	protected void map(LongWritable key, Text value,
			Mapper<LongWritable, Text, Text, Traffic>.Context context)
			throws IOException, InterruptedException {
			//把读入的value转换成字符串 根据TAb键把一行分隔成单个的单词
			String[] values = value.toString().split("\t");
			Text outkey = new Text(values[1]);
			long t1 = Long.parseLong(values[6]);
			long t2 = Long.parseLong(values[7]);
			long t3 = Long.parseLong(values[8]);
			long t4 = Long.parseLong(values[9]);
			Traffic tf = new Traffic();
			tf.setT1(t1);
			tf.setT2(t2);
			tf.setT3(t3);
			tf.setT4(t4);
			context.write(outkey, tf);
	}
	
}
package com.myreduce;

import java.io.IOException;

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

public class TrafficReduce extends Reducer<Text, Traffic, Text, Traffic>{

	@Override
	protected void reduce(Text key, Iterable<Traffic> value,
			Reducer<Text, Traffic, Text, Traffic>.Context context)
			throws IOException, InterruptedException {
			//reduce任务是把多个map任务的输出合并排序 把相同key的value放入同一个集合中
			//将输入的key value对解析成新的keyvalue对 输出
			//此处的key值不需要动 可以原样输出  相同的key的value进行合并
			int sum1 = 0;
			int sum2 = 0;
			int sum3 = 0;
			int sum4 = 0;
			for(Traffic s : value){
				sum1 += s.getT1();
				sum2 += s.getT2();
				sum3 += s.getT3();
				sum4 += s.getT4();
			}
			context.write(key, new Traffic(sum1,sum2,sum3,sum4));
	}
	
}
package com.myreduce;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
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.input.TextInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;

public class TrafficApp {
	public static void main(String[] args) throws Exception {
		Configuration conf = new Configuration();
		conf.set("fs.defaultFS", "file:///");
		Job job = Job.getInstance(conf);
		
		//设置job的属性
		job.setJobName("trafficapp");
		job.setJarByClass(Traffic.class);
		job.setInputFormatClass(TextInputFormat.class);
		
		//设置输入输出路径
		FileInputFormat.addInputPath(job, new Path("file:///e:/copy/"));
		FileOutputFormat.setOutputPath(job, new Path("file:///e:/copy/c"));
		
		job.setMapperClass(TrafficMapper.class);
		job.setMapOutputKeyClass(Text.class);
		job.setMapOutputValueClass(Traffic.class);
		
		job.setReducerClass(TrafficReduce.class);
		job.setOutputKeyClass(Text.class);
		job.setOutputValueClass(Traffic.class);
		
		job.waitForCompletion(true);
	}
}

上述是在本地执行的 我们还要在hadoop集群上去执行 (hdfs 和yarn都需要启动)

把第一个file:注释掉  两个路径改为args[0]    args[1]

打成jar包 传入Linux中   还需要把需要处理的文件传到hdfs上     输入输出路径都要在hdfs上

 $>hadoop jar MyMapReduce.jar com.shulian.mr.WCApp 输入路径 输出路径

总结

今天主要就是会运用自定义的Writable类 理解每一步的过程 能够在hadoop集群上运行即可

理解一下序列化   hadoop的数据对应的java的数据

查看是否传输成功192.168.163.101:8088  8088端口去看整个的运作过程


遇到的错误异常

1.抛出数组越界的异常  :原因是分隔符的问题“\t”代表的是table键 我把斜杠打反了

2.甩出一个io异常,数据类型有问题   原因是我把App这个类里面定义Map的输出类型时定义错误

3.没有权限,无法创建文件     原因是我的file没写冒号............

标题基于Python的汽车之家网站舆情分析系统研究AI更换标题第1章引言阐述汽车之家网站舆情分析的研究背景、意义、国内外研究现状、论文方法及创新点。1.1研究背景与意义说明汽车之家网站舆情分析对汽车行业及消费者的重要性。1.2国内外研究现状概述国内外在汽车舆情分析领域的研究进展与成果。1.3论文方法及创新点介绍本文采用的研究方法及相较于前人的创新之处。第2章相关理论总结和评述舆情分析、Python编程及网络爬虫相关理论。2.1舆情分析理论阐述舆情分析的基本概念、流程及关键技术。2.2Python编程基础介绍Python语言特点及其在数据分析中的应用。2.3网络爬虫技术说明网络爬虫的原理及在舆情数据收集中的应用。第3章系统设计详细描述基于Python的汽车之家网站舆情分析系统的设计方案。3.1系统架构设计给出系统的整体架构,包括数据收集、处理、分析及展示模块。3.2数据收集模块设计介绍如何利用网络爬虫技术收集汽车之家网站的舆情数据。3.3数据处理与分析模块设计阐述数据处理流程及舆情分析算法的选择与实现。第4章系统实现与测试介绍系统的实现过程及测试方法,确保系统稳定可靠。4.1系统实现环境列出系统实现所需的软件、硬件环境及开发工具。4.2系统实现过程详细描述系统各模块的实现步骤及代码实现细节。4.3系统测试方法介绍系统测试的方法、测试用例及测试结果分析。第5章研究结果与分析呈现系统运行结果,分析舆情数据,提出见解。5.1舆情数据可视化展示通过图表等形式展示舆情数据的分布、趋势等特征。5.2舆情分析结果解读对舆情分析结果进行解读,提出对汽车行业的见解。5.3对比方法分析将本系统与其他舆情分析系统进行对比,分析优劣。第6章结论与展望总结研究成果,提出未来研究方向。6.1研究结论概括本文的主要研究成果及对汽车之家网站舆情分析的贡献。6.2展望指出系统存在的不足及未来改进方向,展望舆情
【磁场】扩展卡尔曼滤波器用于利用高斯过程回归进行磁场SLAM研究(Matlab代码实现)内容概要:本文介绍了利用扩展卡尔曼滤波器(EKF)结合高斯过程回归(GPR)进行磁场辅助的SLAM(同步定位与地图构建)研究,并提供了完整的Matlab代码实现。该方法通过高斯过程回归对磁场空间进行建模,有效捕捉磁场分布的非线性特征,同时利用扩展卡尔曼滤波器融合传感器数据,实现移动机器人在复杂环境中的精确定位与地图构建。研究重点在于提升室内等无GPS环境下定位系统的精度与鲁棒性,尤其适用于磁场特征明显的场景。文中详细阐述了算法原理、数学模型构建、状态估计流程及仿真实验设计。; 适合人群:具备一定Matlab编程基础,熟悉机器人感知、导航或状态估计相关理论的研究生、科研人员及从事SLAM算法开发的工程师。; 使用场景及目标:①应用于室内机器人、AGV等在缺乏GPS信号环境下的高精度定位与地图构建;②为磁场SLAM系统的设计与优化提供算法参考和技术验证平台;③帮助研究人员深入理解EKF与GPR在非线性系统中的融合机制及实际应用方法。; 阅读建议:建议读者结合Matlab代码逐模块分析算法实现细节,重点关注高斯过程回归的训练与预测过程以及EKF的状态更新逻辑,可通过替换实际磁场数据进行实验验证,进一步拓展至多源传感器融合场景。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值