Hadoop 原理增强
1hdfs上传原理
- 本地请求上传a.txt 文件
- (1)namenode服务器接受请求、校验
(2)返回ok - 请求上传第一块数据
- namenode接受并返回三个节点地址
- 本地建立连接通道和第一个节点相连接,第一个节点连接第二个节点,第二个节点连接第三个节点
- 原路返回一个ok
- 上传文件
2读取文件原理
1.请求下载a.txt文件
2.接受返回元文件数据信息
3.请求节点下载第一块数据
3.元数据管理
namenode主要负责管理元文件信息
元文件: 文件块储存位置 储存大小 数量 文件的权限
元文件储存在内存和磁盘中。
当用户修改hdfs上的文件时,元数据会发生改变,namenode会修改内存对象数据
为了保证宕机后数据的正确性,我们设计定期将存储元数据对象序列化到磁盘上,主要是分配一个secondary namenode做这件事,namenode自己也可以做
1.加载fsimage——0000镜像文件 反序列化到内存中创建fsimage对象 下载日志文件 正在修改的日志没有,过一段时间或达到一定次数,会将日志序列化到磁盘文件中,然后节点2中的磁盘元数据返回到namenode中,清理之前的磁盘元数据文件和日志。
内存的大小会限制集群的大小。
MapReduce
MR 是一个运算框架,可以处理hdfs文件也可以处理本地文件。
Map阶段
根据自己的任务编号 读取HDFS中要处理属于自己的数据
根据每个单词的hashcode%n 输出到HDFS的文件中 (分区器)
会有一个map程序分别映射属于自己节点的数据块,然后处理,并使用分区器,给下一阶段的节点分配任务。
Reduce阶段
根据自己的任务编号 处理属于自己的文件 汇总结果并输出
也会有一个reduce程序
本地测试实现
目的: 计算一个文件中单词出现的次数
第一步 写一个类继承Mapper
public class MyMapper extends Mapper<LongWritable, Text,Text, IntWritable> {
@Override
protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
String line = value.toString();
String[] words = line.split("\\s+");
for (String word : words) {
Text kout = new Text(word);
IntWritable vout = new IntWritable(1);
context.write(kout,vout);
}
}
}
Mapper类先填写泛型 是hadoop的序列化包装类,用于序列化传输数据
依次是: 起始位置 行数据 输出单词 次数
重写map方法
最后用context 输出
context 用法
>
第二步 写Reduce程序
继承 reducer类 先填写泛型
接受map传来的数据 重写reduce方法
iterable 迭代器 分词器将单词相同的 值都发给reduce统计 统计好发出去
KVIN 和对应的map类的输出的类型一致的
* KVOUT 单词 和 总次数
*/
public class WordCountReducer extends Reducer<Text, IntWritable,Text , IntWritable> {
@Override
protected void reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException {
int cnt = 0 ;
for (IntWritable value : values) {
cnt++ ;
}
IntWritable vout = new IntWritable(cnt);
context.write(key , vout);
}
}
第三步 设置总任务 开始工作
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.awt.*;
import java.io.IOException;
/**
* 在本地模式下运行MR程序
*/
public class DriverWc {
public static void main(String[] args) throws Exception {
Configuration conf = new Configuration();
// 1 初始化一个工作 Job
/**
* 参数一 配置对象 HDFS一样
* 参数二 程序名
*/
Job job = Job.getInstance(conf, "wc");
// 2 设置 Mapper阶段
job.setMapperClass(WordCountMapper.class);
// 3 设置Reducer阶段
job.setReducerClass(WordCountReducer.class);
//--- map阶段的输出数据类型 KV
job.setMapOutputKeyClass(Text.class);
job.setMapOutputValueClass(IntWritable.class);
//--- reduce阶段的输出的数据类型
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(IntWritable.class);
// -- reduce的个数
job.setNumReduceTasks(2);
// 4 处理的数据的位置 输入路径
FileInputFormat.setInputPaths(job,new Path("d://word.txt"));
// 5 输出的结果位置
FileOutputFormat.setOutputPath(job,new Path("d://wc/res_1"));
// 6 提交工作 运行
job.waitForCompletion(true) ;
}
}