简介
一、概述
1.HDFS是Hadoop中用于进行数据分布式存储的模块
二、特点
1.能够存储超大文件-分布式+切块
2.能够快速的应对和检测故障-心跳
3.高可用-副本+双namenode
4.能够动态扩展在廉价机器上-横向扩展
5.不支持低延迟响应
6.不建议存储小文件-每一个小文件会对应一条元数据,大量小文件则会产生大量元数据,元数据多了就会导致元数据的查询效率也变慢
7.简化的一致性模型-允许一次写入多次读取
8.不支持事务
吞吐量-单位时间内节点或者集群读写的数据总量
1s读写100M — 100M/ s
高并发
高吞吐
高并发不一定是高吞吐的(秒杀场景),但是高吞吐一般是高并发的
HDFS Api操作
导包
hadoop插件
删除需要权限
增加环境变量
package cn.tedu.hdfs;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URI;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IOUtils;
import org.junit.Test;
public class HDFSDemo {
//下载
@Test
public void get() throws IOException{
//连接HDFS
//uri 连接地址
//conf 代码中自主指定的配置
Configuration conf=new Configuration();
FileSystem fs=FileSystem.get(
URI.create("hdfs://192.168.253.129:9000"),conf);
//指定下载文件
InputStream in=fs.open(new Path("/a.rpm"));
//创建一个输出流
FileOutputStream out=new FileOutputStream("b.txt");
//读写文件
byte[] bs=new byte[1024];
int len;
while((len=in.read(bs))!=-1){
out.write(bs,0,len);
}
//Hadoop自带的下载api
// IOUtils.copyBytes(in, out, conf);
//关流
in.close();
out.close();
}
//上传
@Test
public void put() throws IOException, InterruptedException{
//连接HDFS
//用于指定属性配置
//凡时放到xxx-site.xml中的配置都可以用conf来指定
//代码中的配置要优先于配置文件中的内容
Configuration conf=new Configuration();
// conf.set("dfs.replication", "3");//副本数,此时在伪分布式中,副本数为1,(因为伪分布式副本数不能多于节点数);真正的分布式可为3
FileSystem fs=FileSystem.get(
URI.create("hdfs://192.168.253.129:9000"),conf,"root");//增加root权限,可以上传操作
//指定上传的文件
OutputStream out=fs.create(new Path("/a.log"));
//创建一个输入读取文件
FileInputStream in=new FileInputStream("b.txt");
//读写文件
IOUtils.copyBytes(in, out, conf);
//关流
in.close();
out.close();
}
//删除
@Test
public void delete() throws Exception{
Configuration conf=new Configuration();
FileSystem fs=FileSystem.get(
URI.create("hdfs://192.168.253.129:9000"),conf,"root");
fs.delete(new Path("/user"));
}
}
MapReduce
简介
一、概述
1.MapReduce是Hadoop提供的一套用于进行分布式计算的框架
2.将计算过程拆分为2个阶段:Map(映射)阶段和Reduce(规约)阶段
原始的mapreduce的代码执行方式,打成jar包,部署到服务器执行
执行脚本
[root@hadoop01 ~]# hadoop jar wc.jar
注意上述步骤缺一不可,代码中不能有super.map(key, value, context);否则报错
mapper
package cn.tedu.wordcount;
import java.io.IOException;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper;
//需要指定Map阶段的处理逻辑
//MapReduce中,要求所有的对象都能够被序列化
//MapReduce所默认采取的序列化机制是AVRO
//KEYIN 输入的键的类型–默认输入的键表示的是一行数据的字节偏移量
//VALUEIN 输入的值的类型–默认输入的值表示的是读取的—行数据
//KEYOUT 输出键的类型
//VALUEOUT 输出值的类型
public class WordCountMapper
extends Mapper<LongWritable,Text,Text,IntWritable>{
//key 行偏移量
//value 一行数据
//context 用于数据传递和指定环境参数
@Override
protected void map(LongWritable key, Text value, Mapper<LongWritable, Text, Text, IntWritable>.Context context)
throws IOException, InterruptedException {
//hello tom hello bob
//先将这一行中的每个单词拆分出来
String[] arr = value.toString().split(" ");
//hello 2 tom 1 bob 1
//hello 1 tom 1 hello 1 bob 1
for (String str : arr) {
context.write(new Text(str), new IntWritable(1));
}
}
}
reducer
package cn.tedu.wordcount;
import java.io.IOException;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer;
//Reduce的数据从Map来,那么也就意味着Map的输出就是Reduce的输入
//KEYIN,VALUEIN
//最后应该是输出每一个单词对应的总次数
//KEYOUT,VALUEOUT
public class WordCountReducer
extends Reducer<Text,IntWritable,Text,IntWritable>{
// key -输入的键
// values -键所对应的所有的值
// hello
// values = 1,1,1,1,1,1,1...
// context -将结果写到HDFS上
@Override
protected void reduce(Text key, Iterable<IntWritable> values,
Reducer<Text, IntWritable, Text, IntWritable>.Context context) throws IOException, InterruptedException {
int sum=0;
for (IntWritable val : values) {
sum+=val.get();
}
context.write(key, new IntWritable(sum));
}
}
driver
package cn.tedu.wordcount;
import java.io.IOException;
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.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
//入口类
public class WordCountDriver {
public static void main(String[] args) throws IOException, ClassNotFoundException, InterruptedException {
//先向Hadoop申请一个job任务执行逻辑
Job job=Job.getInstance();
//设置入口类
job.setJarByClass(WordCountDriver.class);
//设置Mapper类
job.setMapperClass(WordCountMapper.class);
//设置Reducer类
job.setReducerClass(WordCountReducer.class);
//设置Mapper的输出类型
job.setMapOutputKeyClass(Text.class);
job.setMapOutputValueClass(IntWritable.class);
//设置Reduce的输出类型
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(IntWritable.class);
//设置输入文件
FileInputFormat.setInputPaths(job, new Path("hdfs://192.168.253.129:9000/mr/words.txt"));
//设置输出路径
//输出路径要求不存在
FileOutputFormat.setOutputPath(job, new Path("hdfs://192.168.253.129:9000/result/wordcount"));
//启动执行
job.waitForCompletion(true);
}
}
hadoop兼容windows操作
注意:点击winutils.exe没有一个黑窗口闪过,而是报错,应该是不兼容导致(系统是盗版),可以拷贝一份msvcr120.dll到C:\Windows\System32这个目录下一份
直接创建一个mapper
直接创建一个reducer
直接创建一个driver
组件
一、序列化
1.在MapReduce中,要求数据能够被序列化
2. MapReduce的序列化机制默认采用的AVRO
3. MapReduce对AVRo的序列化机制进行了封装,提供了更简便的序列化形式—实现Writable接口
场景:
统计每一个人花费的总流量
统计每一个城市中每一个人花费的总流量
在进行汇总之前,需要先按照地区将数据分类
分类之前和分类之后,Map和Reduce的逻辑
Map - Partitioner - Reduce
二、分区- Partition
1.分区的作用是将数据进行分类
2.有无分区并不影响Map和Reduce的执行逻辑
3.分区默认是从o开始依次递增的
4.在MapReduce中,每一个分区要对应一个ReduceTask,默认情况下只有1个分
区,也就只有1个ReduceTask,只产生一个结果文件
0.按月份统计每一个人的总成绩(score1.txt)
1.输出每一个单词出现的文件(目录:invert )a b c
import org.apache.hadoop.mapreduce.lib.input.FileSplit;
FileSplit fs = (FileSplit)context.getInputSplit();
String name = fs.getPath().getName();
2.找出隐藏好友