HaDoop学习笔记
Hadoop学习笔记
HDFS常用命令
本地->hdfs
put 将本地文件拷贝到hdfs上。
hadoop dfs -put 本地文件名 hdfs路径名
moveFromLocal 将本地文件剪切到本地文件上
hadoop dfs -moveFromLocal 本地文件名 hdfs路径名
appendToFile 将本地文件追加到hdfs的文件后面
hadoop dfs -appendToFile 本地文件名 hdfs文件名
HDFS->HDFS
cp 复制
hadoop dfs -cp hdfs文件名 复制粘贴的新文件名
mv 移动
hadoop dfs -mv hdfs文件名 要移动到的新文件名
chown chgrp chmod 修改文件属性
使用方法同Linux
du 查看磁盘使用情况
df 查看文件占用空间
cat 查看文件
rm 删除文件, -r 就是递归删除
hdfs -> 本地
get 从hdfs 下载到本地
hadoop dfs -get hdfs文件名 本地路径名
getmerge 把hdfs里某个文件夹所有文件文件合并一下并下载到本地
hadoop fs -getmerge 文件夹名 合并后的文件名
用Java代码操作HDFS
@Test
public void put() throws IOException, InterruptedException {
//获取文件系统,
FileSystem fileSystem = FileSystem.get(URI.create("hdfs://hadoop102:9000"), new Configuration(), "root");
//执行操作
fileSystem.copyFromLocalFile(new Path("D:/1.txt"), new Path("/"));
//关闭文件系统
fileSystem.close();
}
MapReduce入门
一个完整的MapReduce分为3部分,分别为Mapper, Reducer, Driver。
Maper需要继承Mapper类。并重写map方法。
Reducer需要继承Reducer类,并重写reduce方法。
Driver不需要继承类。
首先依赖文件:
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>RELEASE</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.8.2</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-common</artifactId>
<version>2.7.2</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-client</artifactId>
<version>2.7.2</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-hdfs</artifactId>
<version>2.7.2</version>
</dependency>
</dependencies>
然后是Mapper
package com.gaolei.mapreduce;
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;
/**
* @author
* @version 1.0
* @date 2020/2/23 13:50
*/
public class WordcountMapper extends Mapper<LongWritable, Text, Text, IntWritable> {
Text text = new Text();
IntWritable writable = new IntWritable();
@Override
protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
//拿到这一行数据
String line = value.toString();
//按照空格切分数据
String[] words = line.split("\\s");
//遍历数组,把单词变成word,1 的形式输回给框架
for (String word : words) {
text.set(word);
writable.set(1);
context.write(text, writable);
}
}
}
Reducer如下:
package com.gaolei.mapreduce;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer;
import java.io.IOException;
/**
* @author
* @version 1.0
* @date 2020/2/23 15:04
*/
public class WordcountReducer extends Reducer<Text , IntWritable, Text, IntWritable> {
private IntWritable total = new IntWritable();
@Override
protected void reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException {
int sum = 0;
for (IntWritable value : values) {
sum += value.get();
}
total.set(sum);
context.write(key, total);
}
}
Driver如下:
package com.gaolei.mapreduce;
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.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import java.io.IOException;
/**
* @author
* @version 1.0
* @date 2020/2/23 15:21
*/
public class WordcountDriver {
public static void main(String[] args) throws IOException, ClassNotFoundException, InterruptedException {
// 1. 获取一个job实例
Job job = Job.getInstance(new Configuration());
//2. 设置类路经
job.setJarByClass(WordcountDriver.class);
//3. 设置mapper和reducer。
job.setMapperClass(WordcountMapper.class);
job.setReducerClass(WordcountReducer.class);
//4. 设置Mapper和Reducer输出的类型
job.setMapOutputKeyClass(Text.class);
job.setMapOutputValueClass(IntWritable.class);
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(IntWritable.class);
//5. 设置输入输出数据
FileInputFormat.setInputPaths(job, new Path(args[0]));
FileOutputFormat.setOutputPath(job, new Path(args[1]));
//6.提交job
boolean b = job.waitForCompletion(true);
if (b) {
System.out.println("成功");
} else {
System.out.println("失败");
}
}
}
如果想让这个示例在集群中运行,就要打包好jar包,然后上传到集群主机上。
执行hadooop jar jar包名字 你写的主类得完全限定名 第一个参数(输入文件) 第二个参数(输出文件)
Hadoop的序列化
没有使用Java的序列化,而是自己写了一套,叫做writable
你写的bean类,实现Writable接口,并实现接口里面的两个方法即可。分别是write和readFields方法。
write方法的话,会有一个DataOutput类型的out参数,他就是框架给我们提供的数据出口,所以,把要序列化的内容,写在out里即可。
而反序列化方法readFields方法。他会有一个DataInput类型的in参数,从他里面拿参数即可。
注意点:序列化和反序列化的顺序要完全一致。
关于数据切片
- 一个job的map阶段并行度由客户端在提交job时的切片数决定。
- 每一个split切片分配一个maptask并行实例处理。
- 默认情况下,切片大小 = BlockSize
- 切片时不考虑数据集整体,而是逐个针对每一个文件单独切片。
尘嚣看不见,你沉醉了没