Hadoop 原理增强

1hdfs上传原理

hadoop元数据管理流程 hadoop元数据管理工具_数据

  1. 本地请求上传a.txt 文件
  2. (1)namenode服务器接受请求、校验
    (2)返回ok
  3. 请求上传第一块数据
  4. namenode接受并返回三个节点地址
  5. 本地建立连接通道和第一个节点相连接,第一个节点连接第二个节点,第二个节点连接第三个节点
  6. 原路返回一个ok
  7. 上传文件

2读取文件原理

hadoop元数据管理流程 hadoop元数据管理工具_数据_02


1.请求下载a.txt文件

2.接受返回元文件数据信息

3.请求节点下载第一块数据

3.元数据管理

hadoop元数据管理流程 hadoop元数据管理工具_hadoop_03


namenode主要负责管理元文件信息

元文件: 文件块储存位置 储存大小 数量 文件的权限

元文件储存在内存和磁盘中。

当用户修改hdfs上的文件时,元数据会发生改变,namenode会修改内存对象数据

为了保证宕机后数据的正确性,我们设计定期将存储元数据对象序列化到磁盘上,主要是分配一个secondary namenode做这件事,namenode自己也可以做

1.加载fsimage——0000镜像文件 反序列化到内存中创建fsimage对象 下载日志文件 正在修改的日志没有,过一段时间或达到一定次数,会将日志序列化到磁盘文件中,然后节点2中的磁盘元数据返回到namenode中,清理之前的磁盘元数据文件和日志。
内存的大小会限制集群的大小。


MapReduce

MR 是一个运算框架,可以处理hdfs文件也可以处理本地文件。

hadoop元数据管理流程 hadoop元数据管理工具_数据_04


hadoop元数据管理流程 hadoop元数据管理工具_hadoop_05


hadoop元数据管理流程 hadoop元数据管理工具_hadoop_06

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) ;


    }
}